diff --git a/Makefile.am b/Makefile.am index f6f13f8b0..2c887df79 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,7 +16,7 @@ SUBDIRS = macros include lib libltdl src @BACKEND_LIST@ @ROT_BACKEND_LIST@ \ DIST_SUBDIRS = macros include lib libltdl src c++ bindings tests doc \ icom kenwood aor yaesu dummy pcr alinco uniden tentec kachina jrc \ rpcrig winradio easycomm fodtrack rpcrot gnuradio drake rotorez \ - microtune flexradio sartek lowe rft tapr kit + microtune flexradio sartek lowe rft tapr kit skanti rpm: Makefile make dist diff --git a/configure.ac b/configure.ac index 68684458c..fd18039d3 100644 --- a/configure.ac +++ b/configure.ac @@ -202,7 +202,7 @@ fi AC_SUBST(RIGMATRIX) -BACKEND_LIST="icom kenwood aor yaesu dummy pcr alinco uniden tentec kachina jrc drake lowe rft kit tapr flexradio" +BACKEND_LIST="icom kenwood aor yaesu dummy pcr alinco uniden tentec kachina jrc drake lowe rft kit skanti tapr flexradio" ROT_BACKEND_LIST="dummy easycomm rotorez sartek fodtrack" BINDINGS="" BINDING_LIST="" @@ -410,6 +410,7 @@ lowe/Makefile rft/Makefile kit/Makefile tapr/Makefile +skanti/Makefile gnuradio/Makefile easycomm/Makefile fodtrack/Makefile diff --git a/skanti/Makefile.am b/skanti/Makefile.am new file mode 100644 index 000000000..1c79b8809 --- /dev/null +++ b/skanti/Makefile.am @@ -0,0 +1,8 @@ +SKANTISRCLIST = trp8000.c + +lib_LTLIBRARIES = hamlib-skanti.la +hamlib_skanti_la_SOURCES = $(SKANTISRCLIST) skanti.c +hamlib_skanti_la_LDFLAGS = -no-undefined -module -avoid-version +hamlib_skanti_la_LIBADD = $(top_builddir)/src/libhamlib.la + +noinst_HEADERS = skanti.h diff --git a/skanti/skanti.c b/skanti/skanti.c new file mode 100644 index 000000000..38d3d1dd8 --- /dev/null +++ b/skanti/skanti.c @@ -0,0 +1,293 @@ +/* + * Hamlib Skanti backend - main file + * Copyright (c) 2004 by Stephane Fillod + * + * $Id: skanti.c,v 1.1 2004-08-18 18:51:24 fillods Exp $ + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include /* String function definitions */ +#include /* UNIX standard function definitions */ +#include + +#include +#include +#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, rig->state!= 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; + struct rig_state *rs; + char retbuf[BUFSZ+1]; + + rs = &rig->state; + + serial_flush(&rs->rigport); + + retval = write_block(&rs->rigport, cmd, cmd_len); + if (retval != RIG_OK) + return retval; + + + /* no data expected, check for OK returned */ + if (!data || !data_len) { + /* + * Transceiver sends back ">" + */ + retval = read_string(&rs->rigport, retbuf, BUFSZ, PROMPT, strlen(PROMPT)); + if (retval < 0 || retval > BUFSZ) + return RIG_ERJCTED; + + retbuf[retval] = '\0'; + + if (strstr(retbuf, PROMPT)) + return RIG_OK; + else + return RIG_ERJCTED; + } + + *data_len = read_string(&rs->rigport, data, BUFSZ, LF, strlen(LF)); + + /* 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); + + return RIG_OK; +} + + + +/* + * skanti_set_freq + * Assumes rig!=NULL + */ +int skanti_set_freq(RIG *rig, vfo_t vfo, freq_t freq) +{ + char freqbuf[BUFSZ]; + int freq_len; + + /* 6 digits */ + freq_len = sprintf(freqbuf, "Z%06ld" EOM, (long)(freq/100)); + + return skanti_transaction (rig, freqbuf, freq_len, 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 %d\n", + __FUNCTION__, mode); + return -RIG_EINVAL; + } + + retval = skanti_transaction (rig, sk_mode, strlen(sk_mode), NULL, NULL); + if (retval != RIG_OK) + 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]; + int freq_len; + + /* 6 digits */ + freq_len = sprintf(freqbuf, "T%06ld" EOM, (long)(tx_freq/100)); + + return skanti_transaction (rig, freqbuf, freq_len, 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) +{ + int cmd_len; + char cmdbuf[BUFSZ], *agc; + + /* Optimize: + * sort the switch cases with the most frequent first + */ + switch (level) { + case RIG_LEVEL_PREAMP: + cmd_len = sprintf(cmdbuf, "R%c" EOM, val.i?'F':'O'); + + return skanti_transaction (rig, cmdbuf, cmd_len, NULL, NULL); + + case RIG_LEVEL_ATT: + cmd_len = sprintf(cmdbuf, "A%c" EOM, val.i?'T':'O'); + + return skanti_transaction (rig, cmdbuf, cmd_len, NULL, NULL); + + case RIG_LEVEL_RFPOWER: + cmd_len = sprintf(cmdbuf, "M%cO" EOM, val.f<0.33?'L':(val.f<0.66?'M':'F')); + + return skanti_transaction (rig, cmdbuf, cmd_len, 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,"Unsupported set_level %d\n", 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]; + int cmd_len; + + cmd_len = sprintf(cmdbuf, "X%c" EOM, ptt == RIG_PTT_ON?'N':'F'); + + return skanti_transaction (rig, cmdbuf, cmd_len, 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, "skanti: _init called\n"); + + rig_register(&trp8000_caps); + + return RIG_OK; +} + diff --git a/skanti/skanti.h b/skanti/skanti.h new file mode 100644 index 000000000..4f8173b2d --- /dev/null +++ b/skanti/skanti.h @@ -0,0 +1,38 @@ +/* + * Hamlib Skanti backend - main header + * Copyright (c) 2004 by Stephane Fillod + * + * $Id: skanti.h,v 1.1 2004-08-18 18:51:24 fillods Exp $ + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _SKANTI_H +#define _SKANTI_H 1 + +#include + +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 const struct rig_caps trp8000_caps; + +#endif /* _SKANTI_H */ diff --git a/skanti/trp8000.c b/skanti/trp8000.c new file mode 100644 index 000000000..8ae146519 --- /dev/null +++ b/skanti/trp8000.c @@ -0,0 +1,134 @@ +/* + * Hamlib Skanti backend - TRP8000 description + * Copyright (c) 2004 by Stephane Fillod + * + * $Id: trp8000.c,v 1.1 2004-08-18 18:51:24 fillods Exp $ + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#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?) + */ +const struct rig_caps trp8000_caps = { +.rig_model = RIG_MODEL_TRP8000, +.model_name = "TRP8000", +.mfg_name = "Skanti", +.version = "0.1", +.copyright = "LGPL", +.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 = 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,100}, + {TRP8000_ALL_MODES,10}, + {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, + +}; + +/* + * Function definitions below + */ +