diff --git a/alinco/Makefile.am b/alinco/Makefile.am new file mode 100644 index 000000000..5c9319aad --- /dev/null +++ b/alinco/Makefile.am @@ -0,0 +1,10 @@ +lib_LTLIBRARIES = libhamlib-alinco.la +libhamlib_alinco_la_SOURCES = dx77.c alinco.c +libhamlib_alinco_la_LDFLAGS = -avoid-version # -module +libhamlib_alinco_la_LIBADD = ../src/libhamlib.la + +lib_LIBRARIES = libhamlib-alinco.a +libhamlib_alinco_a_SOURCES = dx77.c alinco.c +libhamlib_alinco_a_LIBADD = ../src/libhamlib.la + +noinst_HEADERS = alinco.h diff --git a/alinco/Makefile.in b/alinco/Makefile.in new file mode 100644 index 000000000..1a7a5775a --- /dev/null +++ b/alinco/Makefile.in @@ -0,0 +1,418 @@ +# Makefile.in generated automatically by automake 1.4-p2 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 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. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AR = @AR@ +AS = @AS@ +CC = @CC@ +DLLTOOL = @DLLTOOL@ +DLL_PRELOAD = @DLL_PRELOAD@ +ECHO = @ECHO@ +EXEEXT = @EXEEXT@ +INCLTDL = @INCLTDL@ +INCLUDES = @INCLUDES@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBTOOL = @LIBTOOL@ +LIBWINRADIO = @LIBWINRADIO@ +LN_S = @LN_S@ +LTLIBWINRADIO = @LTLIBWINRADIO@ +MAKEINFO = @MAKEINFO@ +NET = @NET@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +RIGMATRIX = @RIGMATRIX@ +STRIP = @STRIP@ +VERSION = @VERSION@ +V_MAJOR = @V_MAJOR@ +V_MINOR = @V_MINOR@ +WINDRES = @WINDRES@ +WINRADIODEPS = @WINRADIODEPS@ +WINRADIOLNK = @WINRADIOLNK@ +hamlibdocdir = @hamlibdocdir@ + +lib_LTLIBRARIES = libhamlib-alinco.la +libhamlib_alinco_la_SOURCES = dx77.c alinco.c +libhamlib_alinco_la_LDFLAGS = -avoid-version # -module +libhamlib_alinco_la_LIBADD = ../src/libhamlib.la + +lib_LIBRARIES = libhamlib-alinco.a +libhamlib_alinco_a_SOURCES = dx77.c alinco.c +libhamlib_alinco_a_LIBADD = ../src/libhamlib.la + +noinst_HEADERS = alinco.h +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../include/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(lib_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I../include +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libhamlib_alinco_a_DEPENDENCIES = ../src/libhamlib.la +libhamlib_alinco_a_OBJECTS = dx77.$(OBJEXT) alinco.$(OBJEXT) +LTLIBRARIES = $(lib_LTLIBRARIES) + +libhamlib_alinco_la_DEPENDENCIES = ../src/libhamlib.la +libhamlib_alinco_la_OBJECTS = dx77.lo alinco.lo +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +DEP_FILES = .deps/alinco.P .deps/dx77.P +SOURCES = $(libhamlib_alinco_a_SOURCES) $(libhamlib_alinco_la_SOURCES) +OBJECTS = $(libhamlib_alinco_a_OBJECTS) $(libhamlib_alinco_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu alinco/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLIBRARIES: + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +distclean-libLIBRARIES: + +maintainer-clean-libLIBRARIES: + +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \ + $(RANLIB) $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LIBRARIES)'; for p in $$list; do \ + rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libhamlib-alinco.a: $(libhamlib_alinco_a_OBJECTS) $(libhamlib_alinco_a_DEPENDENCIES) + -rm -f libhamlib-alinco.a + $(AR) cru libhamlib-alinco.a $(libhamlib_alinco_a_OBJECTS) $(libhamlib_alinco_a_LIBADD) + $(RANLIB) libhamlib-alinco.a + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +libhamlib-alinco.la: $(libhamlib_alinco_la_OBJECTS) $(libhamlib_alinco_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libhamlib_alinco_la_LDFLAGS) $(libhamlib_alinco_la_OBJECTS) $(libhamlib_alinco_la_LIBADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = alinco + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu alinco/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-libLIBRARIES install-libLTLIBRARIES +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-libLIBRARIES uninstall-libLTLIBRARIES +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(libdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-libLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-libLTLIBRARIES \ + mostlyclean-tags mostlyclean-depend mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-libLIBRARIES clean-compile clean-libtool \ + clean-libLTLIBRARIES clean-tags clean-depend \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-libLIBRARIES distclean-compile \ + distclean-libtool distclean-libLTLIBRARIES \ + distclean-tags distclean-depend distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-libLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-libLTLIBRARIES maintainer-clean-tags \ + maintainer-clean-depend maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-libLIBRARIES distclean-libLIBRARIES \ +clean-libLIBRARIES maintainer-clean-libLIBRARIES uninstall-libLIBRARIES \ +install-libLIBRARIES mostlyclean-compile distclean-compile \ +clean-compile maintainer-clean-compile mostlyclean-libtool \ +distclean-libtool clean-libtool maintainer-clean-libtool \ +mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir \ +mostlyclean-depend distclean-depend clean-depend \ +maintainer-clean-depend info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# 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: diff --git a/alinco/alinco.c b/alinco/alinco.c new file mode 100644 index 000000000..e5a0038ae --- /dev/null +++ b/alinco/alinco.c @@ -0,0 +1,834 @@ +/* + * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) + * + * alinco.c - Copyright (C) 2001 Stephane Fillod + * This shared library provides an API for communicating + * via serial interface to a Kenwood radio. + * + * + * $Id: alinco.c,v 1.1 2001-06-03 17:39:59 f4cfe Exp $ + * + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include /* Standard input/output definitions */ +#include /* String function definitions */ +#include /* UNIX standard function definitions */ +#include /* File control definitions */ +#include /* Error number definitions */ +#include /* POSIX terminal control definitions */ +#include +#include + +#include +#include +#include +#include +#include "alinco.h" + + +#define EOM "\r" + +/* + * 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' + +#define AL "AL" +#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 Postion read */ + + +/* + * alinco_transaction + * We assume that rig!=NULL, rig->state!= NULL, data!=NULL, data_len!=NULL + * Otherwise, you'll get a nice seg fault. You've been warned! + * TODO: error case handling + */ +int alinco_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) +{ + int i, count; + struct rig_state *rs; + + rs = &rig->state; + + write_block(rs->fd, cmd, cmd_len, rs->write_delay, rs->post_write_delay); + + /* no data expected, TODO: flush input? */ + if (!data || !data_len) + return 0; + /* + * buffered read are quite helpful here! + * However, an automate with a state model would be more efficient.. + */ + i = 0; + do { + count = fread_block(rs->stream, data+i, 1, rs->timeout); + if (count > 0) + i += count; + } while (count > 0); + + *data_len = i; + + return i; +} + +/* + * alinco_set_vfo + * Assumes rig!=NULL + */ +int alinco_set_vfo(RIG *rig, vfo_t vfo) +{ + char cmdbuf[16]; + int cmd_len; + 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 alinco_transaction (rig, AL CMD_MEMMD "0" EOM, + strlen(AL CMD_MEMMD "0" EOM), NULL, NULL); + default: + rig_debug(RIG_DEBUG_ERR,"alinco_set_vfo: unsupported VFO %d\n", + vfo); + return -RIG_EINVAL; + } + cmd_len = sprintf(cmdbuf, AL CMD_VFO "%c" EOM, vfo_num); + + alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL); + + return RIG_OK; +} + +/* + * alinco_get_vfo + * Assumes rig!=NULL, !vfo + */ +int alinco_get_vfo(RIG *rig, vfo_t *vfo) +{ + char vfobuf[16]; + int vfo_len; + + alinco_transaction(rig, AL CMD_RMV EOM, strlen(AL CMD_RMV EOM), + vfobuf, &vfo_len); + + if (vfo_len != 4 || vfo_len != 6) { + rig_debug(RIG_DEBUG_ERR,"alinco_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, "Memory") || !strcmp(vfobuf, "MEMO")) + *vfo = RIG_VFO_MEM; + else { + rig_debug(RIG_DEBUG_ERR,"alinco_get_vfo: unsupported VFO %s\n", + vfobuf); + return -RIG_EPROTO; + } + return RIG_OK; +} + +/* + * alinco_set_freq + * Assumes rig!=NULL + */ +int alinco_set_freq(RIG *rig, vfo_t vfo, freq_t freq) +{ + char freqbuf[16]; + int freq_len; + + /* max 10 digits */ + if (freq >= GHz(10)) + return -RIG_EINVAL; + + /* at least 6 digits */ + freq_len = sprintf(freqbuf, AL CMD_RXFREQ "%06Ld" EOM, freq); + + alinco_transaction (rig, freqbuf, freq_len, NULL, NULL); + + return RIG_OK; +} + +/* + * where databuf points to a 26 char long buffer + */ +static int current_data_read(RIG *rig, char *databuf) +{ + int data_len; + + alinco_transaction (rig, AL CMD_RDATA EOM, strlen(AL CMD_RDATA EOM), + databuf, &data_len); + + if (data_len != 26) { + rig_debug(RIG_DEBUG_ERR,"alinco_current_data_read: " + "wrong answer %s, len=%d\n", databuf, data_len); + return -RIG_ERJCTED; + } + return RIG_OK; +} + +/* + * alinco_get_freq + * Assumes rig!=NULL, freq!=NULL + */ +int alinco_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) +{ + int retval; + char freqbuf[32]; + + retval = current_data_read(rig, freqbuf); + if (retval != RIG_OK) + return retval; + + /* extract RX freq */ + freqbuf[16] = '\0'; + sscanf(freqbuf+6, "%Ld", freq); + + return RIG_OK; +} + +/* + * alinco_set_mode + * Assumes rig!=NULL + */ +int alinco_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) +{ + char mdbuf[16]; + int mdbuf_len, narrow_filter; + char amode; + + switch (mode) { + /* FIXME: MD_CWL or MD_CWU? */ + case RIG_MODE_CW: 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, + "alinco_set_mode: unsupported mode %d\n", + mode); + return -RIG_EINVAL; + } + + mdbuf_len = sprintf(mdbuf, AL CMD_MODE "%c" EOM, amode); + alinco_transaction (rig, mdbuf, mdbuf_len, NULL, NULL); + + /* + * 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)) + narrow_filter = 1; + else + narrow_filter = 0; + + mdbuf_len = sprintf(mdbuf, AL CMD_FLTER "%02d" EOM, narrow_filter); + alinco_transaction (rig, mdbuf, mdbuf_len, NULL, NULL); + + return RIG_OK; +} + +/* + * alinco_get_mode + * Assumes rig!=NULL, mode!=NULL + */ +int alinco_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) +{ + int retval; + int settings; + char modebuf[32]; + + 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, + "alinco_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; +} + +/* + * icom_set_split + * Assumes rig!=NULL + */ +int icom_set_split(RIG *rig, vfo_t vfo, split_t split) +{ + int cmd_len; + char cmdbuf[32]; + + cmd_len = sprintf(cmdbuf, AL CMD_SPLT "%d" EOM, + split==RIG_SPLIT_ON ? 1 : 0); + + return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL); +} + +/* + * icom_get_split + * Assumes rig!=NULL, split!=NULL + */ +int icom_get_split(RIG *rig, vfo_t vfo, split_t *split) +{ + int splt_len; + char spltbuf[32]; + + alinco_transaction (rig, AL CMD_RSPLT EOM, strlen(AL CMD_RSPLT EOM), + spltbuf, &splt_len); + + if (splt_len != 2) { + rig_debug(RIG_DEBUG_ERR,"alinco_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,"alinco_get_split: unsupported SPLIT %s\n", + spltbuf); + return -RIG_EPROTO; + } + return RIG_OK; +} + +/* + * alinco_set_split_freq + * Assumes rig!=NULL + */ +int alinco_set_split_freq(RIG *rig, vfo_t vfo, freq_t rx_freq, freq_t tx_freq) +{ + char freqbuf[16]; + int freq_len; + int retval; + + /* max 10 digits */ + if (tx_freq >= GHz(10)) + return -RIG_EINVAL; + + retval = alinco_set_freq(rig, vfo, rx_freq); + if (retval != RIG_OK) + return retval; + + /* at least 6 digits */ + freq_len = sprintf(freqbuf, AL CMD_TXFREQ "%06Ld" EOM, tx_freq); + + retval = alinco_transaction (rig, freqbuf, freq_len, NULL, NULL); + + return retval; +} + +/* + * alinco_get_split_freq + * Assumes rig!=NULL, rx_freq!=NULL, tx_freq!=NULL + */ +int alinco_get_split_freq(RIG *rig, vfo_t vfo, freq_t *rx_freq, freq_t *tx_freq) +{ + int retval; + char freqbuf[32]; + + 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, "%Ld", tx_freq); + + /* extract RX freq */ + freqbuf[16] = '\0'; + sscanf(freqbuf+6, "%Ld", rx_freq); + + return RIG_OK; +} + + +/* + * icom_get_rit + * Assumes rig!=NULL, split!=NULL + */ +int icom_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) +{ + int rit_len; + char ritbuf[32]; + + /* read in Hertz unit */ + alinco_transaction (rig, AL CMD_RIT "0" EOM, strlen(AL CMD_RIT "0" EOM), + ritbuf, &rit_len); + + if (rit_len > 5 || (ritbuf[0] != '+' && ritbuf[0] != '-')) { + rig_debug(RIG_DEBUG_ERR,"alinco_get_rit: wrong answer %s, " + "len=%d\n", ritbuf, rit_len); + return -RIG_ERJCTED; + } + ritbuf[rit_len] = '\0'; + + *rit = atoi(ritbuf); + + return RIG_OK; +} + + +/* + * alinco_set_func + * Assumes rig!=NULL + */ +int alinco_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) +{ + int cmd_len; + char cmdbuf[32]; + + /* Optimize: + * sort the switch cases with the most frequent first + */ + switch (func) { + case RIG_FUNC_TONE: + cmd_len = sprintf(cmdbuf, AL CMD_CTCSS "%02d" EOM, status?51:0); + + return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL); + + case RIG_FUNC_FAGC: + cmd_len = sprintf(cmdbuf, AL CMD_AGC "%02d" EOM, status?1:2); + + return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL); + + case RIG_FUNC_NB: + cmd_len = sprintf(cmdbuf, AL CMD_NB "%d" EOM, status?1:0); + + return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL); + + case RIG_FUNC_MON: + cmd_len = sprintf(cmdbuf, AL CMD_MON "%d" EOM, status?1:0); + + return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL); + + default: + rig_debug(RIG_DEBUG_ERR,"Unsupported set_func %d\n", func); + return -RIG_EINVAL; + } + + return RIG_OK; +} + + +/* + * alinco_get_func + * Assumes rig!=NULL, status!=NULL + */ +int alinco_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) +{ + int retval; + int settings; + char funcbuf[32]; + + /* 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", func); + return -RIG_EINVAL; + } + + return RIG_OK; +} + +/* + * alinco_set_level + * Assumes rig!=NULL + * FIXME: cannot support PREAMP and ATT both at same time (make sens though) + */ +int alinco_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + int cmd_len, lvl; + char cmdbuf[32]; + + /* 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; + } + cmd_len = sprintf(cmdbuf, AL CMD_RFGAIN "%02d" EOM, lvl); + + return alinco_transaction (rig, cmdbuf, cmd_len, 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; + } + cmd_len = sprintf(cmdbuf, AL CMD_RFGAIN "%02d" EOM, lvl); + + return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL); + + case RIG_LEVEL_RFPOWER: + cmd_len = sprintf(cmdbuf, AL CMD_PWR "%1d" EOM, val.f<0.5 ? 1 : 0); + + return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL); + + default: + rig_debug(RIG_DEBUG_ERR,"Unsupported get_level %d\n", level); + return -RIG_EINVAL; + } + + return RIG_OK; +} + + +/* + * alinco_get_level + * Assumes rig!=NULL, val!=NULL + */ +int alinco_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + struct alinco_priv_caps *priv; + int retval, lvl_len; + char lvlbuf[32]; + + priv = (struct alinco_priv_caps*)rig->caps->priv; + + /* Optimize: + * sort the switch cases with the most frequent first + */ + switch (level) { + case RIG_LEVEL_STRENGTH: + /* read A/D converted value */ + alinco_transaction (rig, AL CMD_SMETER "1" EOM, + strlen(AL CMD_SMETER "1" EOM), lvlbuf, &lvl_len); + + if (lvl_len != 5) { + rig_debug(RIG_DEBUG_ERR,"alinco_get_level: wrong answer" + "len=%d\n", lvl_len); + return -RIG_ERJCTED; + } + + lvlbuf[5] = '\0'; + val->i = rig_raw2val(atoi(lvlbuf+3), &priv->str_cal); + break; + + case RIG_LEVEL_SQLSTAT: + return -RIG_ENIMPL; /* get_dcd ? */ + + 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: + alinco_transaction (rig, AL CMD_RPOWER EOM, + strlen(AL CMD_RPOWER EOM), lvlbuf, &lvl_len); + + if (lvl_len != 1) { + rig_debug(RIG_DEBUG_ERR,"alinco_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 %d\n", level); + return -RIG_EINVAL; + } + + return RIG_OK; +} + +/* + * alinco_set_ctcss + * Assumes rig!=NULL, rig->caps->ctcss_list != NULL + */ +int alinco_set_ctcss(RIG *rig, vfo_t vfo, tone_t tone) +{ + const struct rig_caps *caps; + unsigned char tonebuf[16]; + int tone_len; + int i; + + caps = rig->caps; + +/* TODO: replace 200 by something like RIGTONEMAX */ + for (i = 0; caps->ctcss_list[i] != 0 && i<200; i++) { + if (caps->ctcss_list[i] == tone) + break; + } + if (caps->ctcss_list[i] != tone) + return -RIG_EINVAL; + + tone_len = sprintf(tonebuf, AL CMD_CTCSS "%02d" EOM, i+1); + + return alinco_transaction (rig, tonebuf, tone_len, NULL, NULL); +} + +/* + * alinco_get_ptt + * Assumes rig!=NULL, ptt!=NULL + */ +int alinco_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) +{ + char pttbuf[16]; + int ptt_len; + + alinco_transaction (rig, AL CMD_PTT EOM, strlen(AL CMD_PTT EOM), + pttbuf, &ptt_len); + + if (ptt_len != 3 || ptt_len != 4) { + rig_debug(RIG_DEBUG_ERR,"alinco_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,"alinco_get_ptt: unknown PTT %s\n", + pttbuf); + return -RIG_EPROTO; + } + return RIG_OK; +} + + +/* + * alinco_get_dcd + * Assumes rig!=NULL, dcd!=NULL + */ +int alinco_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) +{ + char dcdbuf[16]; + int dcd_len; + + alinco_transaction (rig, AL CMD_SQL EOM, strlen(AL CMD_SQL EOM), + dcdbuf, &dcd_len); + + if (dcd_len != 4 || dcd_len != 5) { + rig_debug(RIG_DEBUG_ERR,"alinco_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,"alinco_get_dcd: unknown SQL %s\n", + dcdbuf); + return -RIG_EPROTO; + } + return RIG_OK; +} + +/* + * alinco_set_mem + * Assumes rig!=NULL + * FIXME: check we're in memory mode first + */ +int alinco_set_mem(RIG *rig, vfo_t vfo, int ch) +{ + char cmdbuf[16]; + int cmd_len; + + if (ch < 0 || ch > 99) + return -RIG_EINVAL; + + cmd_len = sprintf(cmdbuf, AL CMD_MCALL "%02d" EOM, ch); + + alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL); + + return RIG_OK; +} + +/* + * alinco_get_mem + * Assumes rig!=NULL, !vfo + */ +int alinco_get_mem(RIG *rig, vfo_t vfo, int *ch) +{ + char membuf[16]; + int mem_len; + + alinco_transaction (rig, AL CMD_RMEM EOM, strlen(AL CMD_RMEM EOM), + membuf, &mem_len); + + if (mem_len != 2) { + rig_debug(RIG_DEBUG_ERR,"alinco_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,"alinco_get_mem: unknown mem %s\n", + membuf); + return -RIG_EPROTO; + } + + return RIG_OK; +} + + +/* + * init_alinco is called by rig_backend_load + */ +int init_alinco(void *be_handle) +{ + rig_debug(RIG_DEBUG_VERBOSE, "alinco: _init called\n"); + + rig_register(&dx77_caps); + + return RIG_OK; +} + diff --git a/alinco/alinco.h b/alinco/alinco.h new file mode 100644 index 000000000..3e8d0a2da --- /dev/null +++ b/alinco/alinco.h @@ -0,0 +1,67 @@ +/* + * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) + * + * alinco.h - Copyright (C) 2001 Stephane Fillod + * This shared library provides an API for communicating + * via serial interface to a Alinco radio. + * + * + * $Id: alinco.h,v 1.1 2001-06-03 17:39:59 f4cfe Exp $ + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _ALINCO_H +#define _ALINCO_H 1 + +#include +#include + +struct alinco_priv_caps { + cal_table_t str_cal; +}; + +int alinco_set_vfo(RIG *rig, vfo_t vfo); +int alinco_get_vfo(RIG *rig, vfo_t *vfo); +int alinco_set_freq(RIG *rig, vfo_t vfo, freq_t freq); +int alinco_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); +int alinco_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); +int alinco_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); +int alinco_set_split(RIG *rig, vfo_t vfo, split_t split); +int alinco_get_split(RIG *rig, vfo_t vfo, split_t *split); +int alinco_set_split_freq(RIG *rig, vfo_t vfo, freq_t rx_freq, freq_t tx_freq); +int alinco_get_split_freq(RIG *rig, vfo_t vfo, freq_t *rx_freq, freq_t *tx_freq); +int alinco_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); +int alinco_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); +int alinco_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int alinco_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); +int alinco_set_parm(RIG *rig, vfo_t vfo, setting_t parm, value_t val); +int alinco_get_parm(RIG *rig, vfo_t vfo, setting_t parm, value_t *val); +int alinco_set_ctcss(RIG *rig, vfo_t vfo, tone_t tone); +int alinco_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); +int alinco_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); +int alinco_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); +int alinco_set_mem(RIG *rig, vfo_t vfo, int ch); +int alinco_get_mem(RIG *rig, vfo_t vfo, int *ch); + +extern const struct rig_caps dx77_caps; + +extern int init_alinco(void *be_handle); + + +#endif /* _ALINCO_H */ + diff --git a/alinco/dx77.c b/alinco/dx77.c new file mode 100644 index 000000000..e9950a815 --- /dev/null +++ b/alinco/dx77.c @@ -0,0 +1,204 @@ +/* + * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) + * + * dx77.c - Copyright (C) 2001 Stephane Fillod + * This shared library provides an API for communicating + * via serial interface to a Alinco radio. + * + * + * $Id: dx77.c,v 1.1 2001-06-03 17:39:59 f4cfe Exp $ + * + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include /* Standard input/output definitions */ +#include /* String function definitions */ +#include /* UNIX standard function definitions */ +#include /* File control definitions */ +#include /* Error number definitions */ +#include /* POSIX terminal control definitions */ +#include + +#include +#include +#include "alinco.h" + + +#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|RIG_FUNC_COMP) + +#define DX77_LEVEL_ALL (RIG_LEVEL_SQLSTAT|RIG_LEVEL_STRENGTH|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 }, \ + } } + +static const struct alinco_priv_caps dx77_priv_caps = { + DX77_STR_CAL +}; + +/* + * 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 + */ +const struct rig_caps dx77_caps = { +rig_model: RIG_MODEL_DX77, +model_name:"DX-77", +mfg_name: "Alinco", +version: "0.1", +copyright: "GPL", +status: RIG_STATUS_UNTESTED, +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: 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, +has_get_level: DX77_LEVEL_ALL, +has_set_level: RIG_LEVEL_SET(DX77_LEVEL_ALL), +has_get_parm: DX77_PARM_ALL, +has_set_parm: RIG_PARM_SET(DX77_PARM_ALL), +level_gran: {}, /* FIXME: granularity */ +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, 0 }, + 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),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_AM|RIG_MODE_FM, kHz(8)}, + {RIG_MODE_AM, kHz(2.7)}, + RIG_FLT_END, + }, +priv: (void*)&dx77_priv_caps, + +set_freq: alinco_set_freq, +get_freq: alinco_get_freq, +set_mode: alinco_set_mode, +get_mode: alinco_get_mode, +set_vfo: alinco_set_vfo, +get_vfo: alinco_get_vfo, +set_split: alinco_set_split, +get_split: alinco_get_split, +set_split_freq: alinco_set_split_freq, +get_split_freq: alinco_get_split_freq, +set_ctcss: alinco_set_ctcss, +get_rit: alinco_get_rit, +get_ptt: alinco_get_ptt, +get_dcd: alinco_get_dcd, +set_func: alinco_set_func, +get_func: alinco_get_func, +set_level: alinco_set_level, +get_level: alinco_get_level, +set_mem: alinco_set_mem, +get_mem: alinco_get_mem, + +}; + +/* + * Function definitions below + */ +