From b57d9e1a375eef8e60d32c7ee32881886a4553eb Mon Sep 17 00:00:00 2001 From: "Nate Bargmann, N0NB" Date: Fri, 29 Oct 2010 21:20:51 +0000 Subject: [PATCH] Support for Elecraft extensions to base Kenwood functions (particularly for the K3). Added debugging print functions to all Kenwood backend functions for easier debugging. git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@3002 7ae35d74-ebe9-4afe-98af-79ac388436b8 --- kenwood/Makefile.am | 2 +- kenwood/elecraft.c | 318 +++++++++++++++++++ kenwood/elecraft.h | 59 ++++ kenwood/k2.c | 217 ++++++------- kenwood/k3.c | 231 ++++++++------ kenwood/kenwood.c | 754 ++++++++++++++++++++++++++++++-------------- kenwood/kenwood.h | 2 +- 7 files changed, 1141 insertions(+), 442 deletions(-) create mode 100644 kenwood/elecraft.c create mode 100644 kenwood/elecraft.h diff --git a/kenwood/Makefile.am b/kenwood/Makefile.am index 95ddef7d0..e47d545a6 100644 --- a/kenwood/Makefile.am +++ b/kenwood/Makefile.am @@ -9,7 +9,7 @@ THSRCLIST = thd7.c thf7.c thg71.c tmd700.c tmv7.c thf6a.c pkglib_LTLIBRARIES = hamlib-kenwood.la hamlib_kenwood_la_SOURCES = $(TSSRCLIST) $(THSRCLIST) $(IC10SRCLIST) \ - kenwood.c th.c ic10.c + kenwood.c th.c ic10.c elecraft.c hamlib_kenwood_la_LDFLAGS = -no-undefined -module -avoid-version hamlib_kenwood_la_LIBADD = $(top_builddir)/src/libhamlib.la @MATH_LIBS@ diff --git a/kenwood/elecraft.c b/kenwood/elecraft.c new file mode 100644 index 000000000..c669de801 --- /dev/null +++ b/kenwood/elecraft.c @@ -0,0 +1,318 @@ +/* + * Hamlib Elecraft backend--support extensions to Kenwood commands + * Copyright (C) 2010 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 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include "token.h" + +#include "elecraft.h" +#include "kenwood.h" + + +/* Actual read extension levels from radio. + * + * Values stored in these variables maps to elecraft_ext_id_string_list.level + * and are only written to by the elecraft_get_extension_level() private + * function during elecraft_open() and thereafter shall be treated as + * READ ONLY! + */ +int k2_ext_lvl; /* Initial K2 extension level */ +int k3_ext_lvl; /* Initial K3 extension level */ + + +static const struct elecraft_ext_id_string elecraft_ext_id_string_list[] = { + { K20, "K20" }, + { K21, "K21" }, + { K22, "K22" }, + { K23, "K23" }, + { K30, "K30" }, + { K31, "K31" }, + { EXT_LEVEL_NONE, NULL }, /* end marker */ +}; + +/* Private function declarations */ +int verify_kenwood_id(RIG *rig, char *id); +int elecraft_get_extension_level(RIG *rig, const char *cmd, int *ext_level); + + +/* 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) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + + int err; + char id[KENWOOD_MAX_BUF_LEN]; + + /* Use check for "ID017;" to verify rig is reachable */ + err = verify_kenwood_id(rig, id); + if (err != RIG_OK) + return err; + + err = elecraft_get_extension_level(rig, "K2", &k2_ext_lvl); + if (err != RIG_OK) + return err; + + /* This command will likely fail on a K2. Needs testing + * to determine proper rig response + */ + err = elecraft_get_extension_level(rig, "K3", &k3_ext_lvl); + if (err != RIG_OK) + rig_debug(RIG_DEBUG_WARN, "%s: K3 probe failed\n", __func__); + + rig_debug(RIG_DEBUG_ERR, "%s: K2 level is %d, %s\n", __func__, + k2_ext_lvl, elecraft_ext_id_string_list[k2_ext_lvl].id); + rig_debug(RIG_DEBUG_ERR, "%s: K3 level is %d, %s\n", __func__, + k3_ext_lvl, elecraft_ext_id_string_list[k3_ext_lvl].id); + + return RIG_OK; +} + + +/* 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) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !mode || !width) + return -RIG_EINVAL; + + char buf[KENWOOD_MAX_BUF_LEN]; + int err; + rmode_t temp_m; + pbwidth_t temp_w; + + 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, "DT", buf, KENWOOD_MAX_BUF_LEN, 4); + if (err != RIG_OK) { + rig_debug(RIG_DEBUG_ERR, "%s: Cannot read K3 DT value\n", __func__); + return err; + } + switch(atoi(&buf[2])) { + case K3_MODE_DATA_A: + *mode = RIG_MODE_PKTUSB; + break; + case K3_MODE_AFSK_A: + *mode = RIG_MODE_RTTY; + break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: unsupported data sub-mode %c\n", __func__, buf[2]); + return -RIG_EINVAL; + } + } else if (temp_m == RIG_MODE_RTTYR) { + err = kenwood_safe_transaction(rig, "DT", buf, KENWOOD_MAX_BUF_LEN, 4); + if (err != RIG_OK) { + rig_debug(RIG_DEBUG_ERR, "%s: Cannot read K3 DT value\n", __func__); + return err; + } + switch(atoi(&buf[2])) { + case K3_MODE_DATA_A: + *mode = RIG_MODE_PKTLSB; + break; + case K3_MODE_AFSK_A: + *mode = RIG_MODE_RTTYR; + break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: unsupported data sub-mode %c\n", __func__, buf[2]); + return -RIG_EINVAL; + } + } 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, "BW", buf, KENWOOD_MAX_BUF_LEN, 7); + if (err != RIG_OK) { + rig_debug(RIG_DEBUG_ERR, "%s: Cannot read K3 BW value\n", __func__); + return err; + } + *width = atoi(&buf[2]) * 10; + + return RIG_OK; +} + + +/* k3_set_mode() + * + * As with k3_get_mode(), the K3 can also set the data submodes which allows + * use of RIG_MODE_PKTUSB and RIG_MODE_PKLSB. + */ + +int k3_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + + int err; + char cmd_s[16]; + + switch (mode) { + case RIG_MODE_PKTLSB: + mode = RIG_MODE_RTTYR; + strncpy(cmd_s, "DT0", 5); + break; + case RIG_MODE_PKTUSB: + mode = RIG_MODE_RTTY; + strncpy(cmd_s, "DT0", 5); + break; + case RIG_MODE_RTTY: + case RIG_MODE_RTTYR: + strncpy(cmd_s, "DT1", 5); + break; + default: + break; + } + + /* 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; + + /* 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_simple_cmd(rig, cmd_s); + if (err != RIG_OK) + return err; + } + + /* 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. + */ + sprintf(cmd_s, "BW%04d", width / 10); + err = kenwood_simple_cmd(rig, cmd_s); + if (err != RIG_OK) + return err; + + return RIG_OK; +} + + + + + +/* Private helper functions */ + +/* Tests for Kenwood ID string of "017" */ + +int verify_kenwood_id(RIG *rig, char *id) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !id) + return -RIG_EINVAL; + + int err; + char *idptr; + + /* Check for an Elecraft K2|K3 which returns "017" */ + err = kenwood_get_id(rig, id); + if (err != RIG_OK) { + rig_debug(RIG_DEBUG_TRACE, "%s: cannot get identification\n", __func__); + return err; + } + + /* ID is 'ID017;' */ + if (strlen(id) < 5) { + rig_debug(RIG_DEBUG_TRACE, "%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_TRACE, "%s: Rig (%s) is not a K2 or K3\n", __func__, id); + return -RIG_EPROTO; + } else + rig_debug(RIG_DEBUG_TRACE, "%s: Rig ID is %s\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) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !ext_level) + return -RIG_EINVAL; + + int err, i; + char buf[KENWOOD_MAX_BUF_LEN]; + char *bufptr; + + err = kenwood_safe_transaction(rig, cmd, buf, KENWOOD_MAX_BUF_LEN, 4); + if (err != RIG_OK) { + rig_debug(RIG_DEBUG_ERR, "%s: Cannot get K2|K3 ID\n", __func__); + return err; + } + + /* Get extension level string */ + bufptr = &buf[0]; + + for (i = 0; elecraft_ext_id_string_list[i].level != EXT_LEVEL_NONE; i++) { + if (strcmp(elecraft_ext_id_string_list[i].id, bufptr) != 0) + continue; + + if (strcmp(elecraft_ext_id_string_list[i].id, bufptr) == 0) { + *ext_level = elecraft_ext_id_string_list[i].level; + rig_debug(RIG_DEBUG_TRACE, "%s: Extension level is %d, %s\n", + __func__, *ext_level, elecraft_ext_id_string_list[i].id); + } + } + + return RIG_OK; +} diff --git a/kenwood/elecraft.h b/kenwood/elecraft.h new file mode 100644 index 000000000..d9a52e50c --- /dev/null +++ b/kenwood/elecraft.h @@ -0,0 +1,59 @@ +/* + * Hamlib Elecraft backend--support extensions to Kenwood commands + * Copyright (C) 2010 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 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _ELECRAFT_H +#define _ELECRAFT_H 1 + + +/* The Elecraft Programmer's Reference details the extension level that + * a K2 or K3 may have in effect which modify certain commands. + */ + +#define EXT_LEVEL_NONE -1 + +enum elecraft_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 */ +}; + +struct elecraft_ext_id_string { + enum elecraft_ext_id_e level; + const char *id; +}; + +/* Data sub-modes are provide 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; */ +}; + + +/* Elecraft extension function declarations */ +int elecraft_open(RIG *rig); +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); + +#endif /* _ELECRAFT_H */ diff --git a/kenwood/k2.c b/kenwood/k2.c index 6395abcae..d71458b39 100644 --- a/kenwood/k2.c +++ b/kenwood/k2.c @@ -28,6 +28,7 @@ #include #include "kenwood.h" +#include "elecraft.h" #define K2_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) @@ -53,127 +54,129 @@ static struct kenwood_priv_caps k2_priv_caps = { * part of infos comes from http://www.elecraft.com */ const struct rig_caps k2_caps = { -.rig_model = RIG_MODEL_K2, -.model_name = "K2", -.mfg_name = "Elecraft", -.version = BACKEND_VER, -.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_NONE, -.write_delay = 0, -.post_write_delay = 0, -.timeout = 600, -.retry = 3, + .rig_model = RIG_MODEL_K2, + .model_name = "K2", + .mfg_name = "Elecraft", + .version = BACKEND_VER, + .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_NONE, + .write_delay = 0, + .post_write_delay = 0, + .timeout = 600, + .retry = 3, -.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 = {}, /* FIXME: granularity */ -.parm_gran = {}, -.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, + .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 = {}, /* FIXME: granularity */ + .parm_gran = {}, + .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 = { RIG_CHAN_END }, + .chan_list = { 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_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 = { + .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_RTTY|RIG_MODE_RTTYR, Hz(500)}, RIG_FLT_END, }, -.priv = (void *)&k2_priv_caps, + .priv = (void *)&k2_priv_caps, -.rig_init = kenwood_init, -.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, -.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_level = kenwood_set_level, -.get_level = kenwood_get_level, -.vfo_op = kenwood_vfo_op, -.set_trn = kenwood_set_trn, -.get_trn = kenwood_get_trn, -.get_powerstat = kenwood_get_powerstat, -.set_ant = kenwood_set_ant, -.get_ant = kenwood_get_ant, -.send_morse = kenwood_send_morse, + .rig_init = kenwood_init, + .rig_cleanup = kenwood_cleanup, + .rig_open = elecraft_open, + .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, + .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_level = kenwood_set_level, + .get_level = kenwood_get_level, + .vfo_op = kenwood_vfo_op, + .set_trn = kenwood_set_trn, + .get_trn = kenwood_get_trn, + .get_powerstat = kenwood_get_powerstat, + .set_ant = kenwood_set_ant, + .get_ant = kenwood_get_ant, + .send_morse = kenwood_send_morse, }; /* - * Function definitions below + * Function definitions in elecraft.c */ diff --git a/kenwood/k3.c b/kenwood/k3.c index 9464e276f..03b251708 100644 --- a/kenwood/k3.c +++ b/kenwood/k3.c @@ -2,8 +2,6 @@ * Hamlib Kenwood backend - Elecraft K3 description * Copyright (c) 2002-2009 by Stephane Fillod * - * $Id: k3.c,v 1.4 2009-02-10 22:51:21 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 @@ -29,10 +27,11 @@ #include #include "kenwood.h" #include "bandplan.h" - +#include "elecraft.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_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_LOCK) @@ -50,125 +49,147 @@ static struct kenwood_priv_caps k3_priv_caps = { .cmdtrm = EOM_KEN, }; + /* * KIO3 rig capabilities. - * This kit can recognize a large subset of TS-570/K2 commands. + * 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). * - * part of infos comes from http://www.elecraft.com + * Part of info comes from http://www.elecraft.com/K2_Manual_Download_Page.htm#K3 + * look for K3 Programmer's Reference PDF */ const struct rig_caps k3_caps = { -.rig_model = RIG_MODEL_K3, -.model_name = "K3", -.mfg_name = "Elecraft", -.version = BACKEND_VER, -.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 = 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 = 600, /* FA and FB make take up to 500 ms on band change */ -.retry = 3, + .rig_model = RIG_MODEL_K3, + .model_name = "K3", + .mfg_name = "Elecraft", + .version = "20101027", + .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 = 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 = 600, /* FA and FB make take up to 500 ms on band change */ + .retry = 3, -.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 = {}, /* FIXME: granularity */ -.parm_gran = {}, -.preamp = { 14, 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, -.transceive = RIG_TRN_RIG, -.bank_qty = 0, -.chan_desc_sz = 0, + .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 = {}, /* FIXME: granularity */ + .parm_gran = {}, + .preamp = { 14, 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, + .transceive = RIG_TRN_RIG, + .bank_qty = 0, + .chan_desc_sz = 0, -.chan_list = { RIG_CHAN_END }, + .chan_list = { 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_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! */ -.filters = { - {RIG_MODE_SSB, kHz(2.5)}, - {RIG_MODE_CW|RIG_MODE_CWR, Hz(500)}, + .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! */ + .filters = { + {RIG_MODE_SSB, kHz(2.7)}, + {RIG_MODE_SSB, kHz(2.8)}, + {RIG_MODE_SSB, kHz(1.8)}, + {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, 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, 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, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, - {RIG_MODE_FM, kHz(6)}, /* TBC */ + {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, + .priv = (void *)&k3_priv_caps, -.rig_init = kenwood_init, -.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, -.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_level = kenwood_set_level, -.get_level = kenwood_get_level, -.vfo_op = kenwood_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, -.get_ant = kenwood_get_ant, -.send_morse = kenwood_send_morse, + .rig_init = kenwood_init, + .rig_cleanup = kenwood_cleanup, + .rig_open = elecraft_open, + .set_freq = kenwood_set_freq, + .get_freq = kenwood_get_freq, + .set_mode = k3_set_mode, + .get_mode = k3_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_level = kenwood_set_level, + .get_level = kenwood_get_level, + .vfo_op = kenwood_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, + .get_ant = kenwood_get_ant, + .send_morse = kenwood_send_morse, }; /* - * Function definitions below + * K3 extension function definitions in elecraft.c */ diff --git a/kenwood/kenwood.c b/kenwood/kenwood.c index 177a4ff0d..527d9a70e 100644 --- a/kenwood/kenwood.c +++ b/kenwood/kenwood.c @@ -71,7 +71,7 @@ static const struct kenwood_id kenwood_id_list[] = { { RIG_MODEL_TS690S, 11 }, { RIG_MODEL_TS870S, 15 }, { RIG_MODEL_TRC80, 16 }, - { RIG_MODEL_TS570D, 17 }, /* Elecraft K2 also returns 17 */ + { RIG_MODEL_TS570D, 17 }, /* Elecraft K2|K3 also returns 17 */ { RIG_MODEL_TS570S, 18 }, { RIG_MODEL_TS2000, 19 }, { RIG_MODEL_TS480, 20 }, @@ -92,7 +92,7 @@ static const struct kenwood_id_string kenwood_id_string_list[] = { { RIG_MODEL_TS450S, "010" }, { RIG_MODEL_TS690S, "011" }, { RIG_MODEL_TS870S, "015" }, - { RIG_MODEL_TS570D, "017" }, /* Elecraft K2 also returns 17 */ + { RIG_MODEL_TS570D, "017" }, /* Elecraft K2|K3 also returns 17 */ { RIG_MODEL_TS570S, "018" }, { RIG_MODEL_TS2000, "019" }, { RIG_MODEL_TS480, "020" }, @@ -135,44 +135,50 @@ const tone_t kenwood38_ctcss_list[] = { * kenwood_transaction * Assumes rig!=NULL rig->state!=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). - * 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. + * 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). + * cmd_len: Not used + * 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: 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 occured. - * RIG_EIO - if an I/O error occured 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. + * RIG_OK - if no error occured. + * RIG_EIO - if an I/O error occured 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, int cmd_len, +int kenwood_transaction(RIG *rig, const char *cmdstr, int cmd_len, char *data, size_t *datasize) { - struct kenwood_priv_caps *caps = kenwood_caps(rig); - struct rig_state *rs; - int retval; - char cmdtrm[2]; /* Default Command/Reply termination char */ - int retry_read = 0; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - rs = &rig->state; - rs->hold_decode = 1; + if (!rig || !datasize) + return -RIG_EINVAL; - rig_debug(RIG_DEBUG_TRACE, "%s: %s\n", __func__, cmdstr); + struct kenwood_priv_caps *caps = kenwood_caps(rig); + struct rig_state *rs; + int retval; + char cmdtrm[2]; /* Default Command/Reply termination char */ + int retry_read = 0; - cmdtrm[0] = caps->cmdtrm; - cmdtrm[1] = '\0'; + rs = &rig->state; + rs->hold_decode = 1; + + rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, cmdstr); + + cmdtrm[0] = caps->cmdtrm; + cmdtrm[1] = '\0'; transaction_write: - serial_flush(&rs->rigport); + serial_flush(&rs->rigport); - if (cmdstr) { + if (cmdstr) { char *cmd; int len = strlen(cmdstr); @@ -197,100 +203,125 @@ transaction_write: if (retval != RIG_OK) goto transaction_quit; - } + } - if (data == NULL || *datasize <= 0) { - rig->state.hold_decode = 0; - return RIG_OK; /* don't want a reply */ - } + if (data == NULL || *datasize <= 0) { + rig->state.hold_decode = 0; + return RIG_OK; /* don't want a reply */ + } - memset(data,0,*datasize); - retval = read_string(&rs->rigport, data, *datasize, cmdtrm, strlen(cmdtrm)); - if (retval < 0) { - if (retry_read++ < rig->state.rigport.retry) - goto transaction_write; - goto transaction_quit; - } else - *datasize = retval; + memset(data,0,*datasize); + retval = read_string(&rs->rigport, data, *datasize, cmdtrm, strlen(cmdtrm)); + if (retval < 0) { + if (retry_read++ < rig->state.rigport.retry) + goto transaction_write; + goto transaction_quit; + } + else + *datasize = retval; - /* Check that command termination is correct */ - if (strchr(cmdtrm, data[strlen(data)-1])==NULL) { - rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, data); - if (retry_read++ < rig->state.rigport.retry) - goto transaction_write; - retval = -RIG_EPROTO; - goto transaction_quit; - } + /* Check that command termination is correct */ + if (strchr(cmdtrm, data[strlen(data)-1])==NULL) { + rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, data); + if (retry_read++ < rig->state.rigport.retry) + goto transaction_write; + retval = -RIG_EPROTO; + goto transaction_quit; + } - if (strlen(data) == 2) { + if (strlen(data) == 2) { switch (data[0]) { case 'N': - /* Command recognised by rig but invalid data entered. */ - rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, cmdstr); - retval = -RIG_ENAVAIL; - goto transaction_quit; + /* Command recognised by rig but invalid data entered. */ + 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 */ - rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, cmdstr); + rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, cmdstr); if (retry_read++ < rig->state.rigport.retry) goto transaction_write; - retval = -RIG_EPROTO; - goto transaction_quit; + retval = -RIG_EPROTO; + goto transaction_quit; case 'E': /* Communication error */ - rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__, cmdstr); + rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__, cmdstr); if (retry_read++ < rig->state.rigport.retry) goto transaction_write; - retval = -RIG_EIO; - goto transaction_quit; + retval = -RIG_EIO; + goto transaction_quit; case '?': - /* Command not understood by rig */ - rig_debug(RIG_DEBUG_ERR, "%s: Unknown command '%s'\n", __func__, cmdstr); + /* Command not understood by rig */ + rig_debug(RIG_DEBUG_ERR, "%s: Unknown command '%s'\n", __func__, cmdstr); if (retry_read++ < rig->state.rigport.retry) goto transaction_write; - retval = -RIG_ERJCTED; - goto transaction_quit; + retval = -RIG_ERJCTED; + goto transaction_quit; + } } - } - /* always give back a null terminated string without + /* always give back a null terminated string without * the command terminator. */ - if (strlen(data) > 0) - data[strlen(data) - 1] = '\0'; /* not elegant, but works */ + data[strlen(data) - 1] = '\0'; /* not elegant, but works */ else - data[0] = '\0'; - /* - * Check that received the correct reply. The first two characters - * should be the same as command. - */ - if (cmdstr && (data[0] != cmdstr[0] || data[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__, data[0], data[1], cmdstr[0], cmdstr[1]); + data[0] = '\0'; - if (retry_read++ < rig->state.rigport.retry) - goto transaction_write; + /* + * Check that we received the correct reply. The first two characters + * should be the same as command. + */ + if (cmdstr && (data[0] != cmdstr[0] || data[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__, data[0], data[1], cmdstr[0], cmdstr[1]); - retval = -RIG_EPROTO; - goto transaction_quit; - } + if (retry_read++ < rig->state.rigport.retry) + goto transaction_write; + + retval = -RIG_EPROTO; + goto transaction_quit; + } + + retval = RIG_OK; - retval = RIG_OK; transaction_quit: - rs->hold_decode = 0; - return retval; + + rs->hold_decode = 0; + return retval; } -int -kenwood_safe_transaction(RIG *rig, const char *cmd, char *buf, + +/** + * 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 occured. + * 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) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !buf) + return -RIG_EINVAL; + int err; if (expected == 0) @@ -301,7 +332,7 @@ kenwood_safe_transaction(RIG *rig, const char *cmd, char *buf, return err; if (buf_size != expected) { - rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len for cmd %s: " + rig_debug(RIG_DEBUG_ERR, "%s: wrong answer; len for cmd %s: " "expected = %d, got %d\n", __func__, cmd, expected, buf_size); return -RIG_EPROTO; @@ -312,6 +343,8 @@ kenwood_safe_transaction(RIG *rig, const char *cmd, char *buf, 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]; @@ -320,6 +353,9 @@ rmode_t kenwood2rmode(unsigned char mode, const rmode_t mode_table[]) char rmode2kenwood(rmode_t mode, const rmode_t mode_table[]) { int i; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + for(i = 0; i < KENWOOD_MODE_TABLE_MAX; i++) { if (mode_table[i] == mode) return i; @@ -329,10 +365,15 @@ char rmode2kenwood(rmode_t mode, const rmode_t mode_table[]) int kenwood_init(RIG *rig) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + struct kenwood_priv_data *priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); - rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); +// rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); priv = malloc(sizeof(struct kenwood_priv_data)); if (priv == NULL) @@ -359,9 +400,14 @@ int kenwood_init(RIG *rig) int kenwood_cleanup(RIG *rig) { - if (rig == NULL) + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) return -RIG_EINVAL; +// if (rig == NULL) +// return -RIG_EINVAL; + free(rig->state.priv); rig->state.priv = NULL; @@ -370,23 +416,27 @@ int kenwood_cleanup(RIG *rig) int kenwood_open(RIG *rig) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + int err, i; char *idptr; char id[KENWOOD_MAX_BUF_LEN]; - rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); +// rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); /* get id in buffer, will be null terminated */ err = kenwood_get_id(rig, id); if (err != RIG_OK) { - rig_debug(RIG_DEBUG_ERR, "%s: cannot get identification\n", - __func__); + 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", id); + rig_debug(RIG_DEBUG_ERR, "%s: unknown id type (%s)\n", __func__, id); return -RIG_EPROTO; } @@ -422,15 +472,37 @@ int kenwood_open(RIG *rig) return -RIG_EPROTO; } -/* caller must give a buffer of KENWOOD_MAX_BUF_LEN size */ + +/* ID + * Reads transceiver ID number + * + * caller must give a buffer of KENWOOD_MAX_BUF_LEN size + * + */ int kenwood_get_id(RIG *rig, char *buf) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + size_t size = KENWOOD_MAX_BUF_LEN; + return kenwood_transaction(rig, "ID", 2, buf, &size); } + +/* IF + * Retrieves the transceiver status + * + */ static int kenwood_get_if(RIG *rig) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + struct kenwood_priv_data *priv = rig->state.priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); @@ -438,12 +510,19 @@ static int kenwood_get_if(RIG *rig) KENWOOD_MAX_BUF_LEN, caps->if_len); } -/* - * kenwood_set_vfo - * Assumes rig!=NULL + +/* 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) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + struct kenwood_priv_data *priv = rig->state.priv; char cmdbuf[6]; int retval; @@ -466,9 +545,8 @@ int kenwood_set_vfo(RIG *rig, vfo_t vfo) case RIG_VFO_CURR: return RIG_OK; - default: - rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %d\n", - __func__, vfo); + default: + rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %d\n", __func__, vfo); return -RIG_EINVAL; } @@ -488,8 +566,18 @@ int kenwood_set_vfo(RIG *rig, vfo_t vfo) return kenwood_simple_cmd(rig, cmdbuf); } + +/* FR FT + * 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) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + struct kenwood_priv_data *priv = rig->state.priv; char cmdbuf[6]; int retval; @@ -501,12 +589,11 @@ int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) 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 %d\n", __func__, - vfo); + default: + rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %d\n", __func__, vfo); return -RIG_EINVAL; } - + /* set RX VFO */ sprintf(cmdbuf, "FR%c", vfo_function); retval = kenwood_simple_cmd(rig, cmdbuf); @@ -515,7 +602,7 @@ int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) } /* Split off means Rx and Tx are the same */ - if (split==RIG_SPLIT_OFF) { + if (split == RIG_SPLIT_OFF) { txvfo = vfo; if (txvfo == RIG_VFO_CURR) { retval = rig_get_vfo(rig, &txvfo); @@ -529,11 +616,10 @@ int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) 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 %d\n", - __func__, txvfo); + default: + rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %d\n", __func__, txvfo); return -RIG_EINVAL; - } + } /* set TX VFO */ sprintf(cmdbuf, "FT%c", vfo_function); retval = kenwood_simple_cmd(rig, cmdbuf); @@ -546,8 +632,18 @@ int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) return 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) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !split || !txvfo) + return -RIG_EINVAL; + struct kenwood_priv_data *priv = rig->state.priv; int retval; @@ -564,7 +660,7 @@ int kenwood_get_split_vfo_if(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo *split = RIG_SPLIT_ON; break; - default: + default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %c\n", __func__, priv->info[32]); return -RIG_EPROTO; @@ -581,10 +677,14 @@ int kenwood_get_split_vfo_if(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo /* * kenwood_get_vfo_if using byte 31 of the IF information field - * Assumes rig!=NULL, !vfo */ int kenwood_get_vfo_if(RIG *rig, vfo_t *vfo) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !vfo) + return -RIG_EINVAL; + int retval; struct kenwood_priv_data *priv = rig->state.priv; @@ -605,7 +705,7 @@ int kenwood_get_vfo_if(RIG *rig, vfo_t *vfo) *vfo = RIG_VFO_MEM; break; - default: + default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, priv->info[30]); return -RIG_EPROTO; @@ -616,10 +716,14 @@ int kenwood_get_vfo_if(RIG *rig, vfo_t *vfo) /* * kenwood_set_freq - * Assumes rig!=NULL */ int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + char freqbuf[16]; unsigned char vfo_letter; vfo_t tvfo; @@ -630,9 +734,8 @@ int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq) case RIG_VFO_A: vfo_letter = 'A'; break; case RIG_VFO_B: vfo_letter = 'B'; break; case RIG_VFO_C: vfo_letter = 'C'; break; - default: - rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %d\n", - __func__, vfo); + default: + rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %d\n", __func__, vfo); return -RIG_EINVAL; } sprintf(freqbuf, "F%c%011ld", vfo_letter, (long)freq); @@ -642,8 +745,12 @@ int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq) int kenwood_get_freq_if(RIG *rig, vfo_t vfo, freq_t *freq) { - struct kenwood_priv_data *priv = rig->state.priv; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + if (!rig || !freq) + return -RIG_EINVAL; + + struct kenwood_priv_data *priv = rig->state.priv; char freqbuf[50]; int retval; @@ -660,10 +767,14 @@ int kenwood_get_freq_if(RIG *rig, vfo_t vfo, freq_t *freq) /* * kenwood_get_freq - * Assumes rig!=NULL, freq!=NULL */ int kenwood_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !freq) + return -RIG_EINVAL; + char freqbuf[50]; char cmdbuf[4]; int retval; @@ -682,7 +793,7 @@ int kenwood_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) case RIG_VFO_A: vfo_letter = 'A'; break; case RIG_VFO_B: vfo_letter = 'B'; break; case RIG_VFO_C: vfo_letter = 'C'; break; - default: + default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %d\n", __func__, vfo); return -RIG_EINVAL; @@ -699,8 +810,13 @@ int kenwood_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) return RIG_OK; } -int kenwood_get_rit(RIG *rig, vfo_t vfo, shortfreq_t * rit) +int kenwood_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !rit) + return -RIG_EINVAL; + int retval; char buf[6]; struct kenwood_priv_data *priv = rig->state.priv; @@ -722,6 +838,11 @@ int kenwood_get_rit(RIG *rig, vfo_t vfo, shortfreq_t * rit) */ int kenwood_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + char buf[4]; int retval, i; @@ -740,23 +861,37 @@ int kenwood_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit) return retval; } -/* +/* * rit and xit are the same */ -int kenwood_get_xit(RIG * rig, vfo_t vfo, shortfreq_t * rit) +int kenwood_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { - return kenwood_get_rit(rig, vfo, rit); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !rit) + return -RIG_EINVAL; + + return kenwood_get_rit(rig, vfo, rit); } -int kenwood_set_xit(RIG * rig, vfo_t vfo, shortfreq_t rit) +int kenwood_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { - return kenwood_set_rit(rig, vfo, rit); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + + return kenwood_set_rit(rig, vfo, rit); } -int kenwood_scan(RIG * rig, vfo_t vfo, scan_t scan, int ch) +int kenwood_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { - return kenwood_simple_cmd(rig, - scan == RIG_SCAN_STOP ? "SC0" : "SC1"); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + + return kenwood_simple_cmd(rig, scan == RIG_SCAN_STOP ? "SC0" : "SC1"); } /* @@ -772,9 +907,14 @@ int kenwood_scan(RIG * rig, vfo_t vfo, scan_t scan, int ch) /* XXX revise */ static int kenwood_set_filter(RIG *rig, pbwidth_t width) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + char *cmd; - if (width <= Hz(250)) + if (width <= Hz(250)) cmd = "FL010009"; else if(width <= Hz(500)) cmd = "FL009009"; @@ -790,10 +930,14 @@ static int kenwood_set_filter(RIG *rig, pbwidth_t width) /* * kenwood_set_mode - * Assumes rig!=NULL */ int kenwood_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + struct kenwood_priv_caps *caps = kenwood_caps(rig); char buf[6]; char kmode; @@ -802,14 +946,14 @@ int kenwood_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) kmode = rmode2kenwood(mode, caps->mode_table); if (kmode < 0 ) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", - __func__, rig_strrmode(mode)); + __func__, rig_strrmode(mode)); return -RIG_EINVAL; } sprintf(buf, "MD%c", '0' + kmode); err = kenwood_simple_cmd(rig, buf); - if (err != RIG_OK) - return err; + if (err != RIG_OK) + return err; if (rig->caps->rig_model == RIG_MODEL_TS450S || rig->caps->rig_model == RIG_MODEL_TS690S @@ -817,59 +961,68 @@ int kenwood_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) err = kenwood_set_filter(rig, width); /* non fatal */ - } + } - return RIG_OK; + return RIG_OK; } static int kenwood_get_filter(RIG *rig, pbwidth_t *width) { - int err, f, f1, f2; - char buf[10]; + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - err = kenwood_safe_transaction(rig, "FL", buf, sizeof(buf), 9); - if (err != RIG_OK) - return err; + if (!rig || !width) + return -RIG_EINVAL; - buf[8] = '\0'; - f2 = atoi(&buf[5]); + int err, f, f1, f2; + char buf[10]; - buf[5] = '\0'; - f1 = atoi(&buf[2]); + err = kenwood_safe_transaction(rig, "FL", buf, sizeof(buf), 9); + if (err != RIG_OK) + return err; - if (f2 > f1) - f = f2; - else - f = f1; + buf[8] = '\0'; + f2 = atoi(&buf[5]); - 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; - } + buf[5] = '\0'; + f1 = atoi(&buf[2]); - return RIG_OK; + 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; } /* * kenwood_get_mode - * Assumes rig!=NULL, mode!=NULL */ int kenwood_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !mode || !width) + return -RIG_EINVAL; + struct kenwood_priv_caps *caps = kenwood_caps(rig); char modebuf[10]; int retval; @@ -889,6 +1042,11 @@ int kenwood_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) /* 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) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !mode || !width) + return -RIG_EINVAL; + int err; struct kenwood_priv_caps *caps = kenwood_caps(rig); struct kenwood_priv_data *priv = rig->state.priv; @@ -914,6 +1072,11 @@ 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) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + char levelbuf[16]; int i, kenwood_val; @@ -986,7 +1149,7 @@ int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return -RIG_EINVAL; sprintf(levelbuf, "SH%02d",(val.i)); break; - + case RIG_LEVEL_SLOPE_LOW: if(val.i>20 || val.i < 0) return -RIG_EINVAL; @@ -1013,11 +1176,13 @@ int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return kenwood_simple_cmd(rig, levelbuf); } -/* - * assumes f!=NULL - */ int get_kenwood_level(RIG *rig, const char *cmd, int cmd_len, float *f) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !cmd || !f) + return -RIG_EINVAL; + char lvlbuf[10]; int retval; int lvl; @@ -1036,10 +1201,14 @@ int get_kenwood_level(RIG *rig, const char *cmd, int cmd_len, float *f) /* * kenwood_get_level - * Assumes rig!=NULL, val!=NULL */ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !val) + return -RIG_EINVAL; + char lvlbuf[50]; int retval; int lvl; @@ -1152,7 +1321,7 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) lvlbuf[4]='\0'; val->i=atoi(&lvlbuf[2]); break; - + case RIG_LEVEL_SLOPE_HIGH: lvl_len = 50; retval = kenwood_transaction (rig, "SH", 3, lvlbuf, &lvl_len); @@ -1200,6 +1369,11 @@ 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) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + char buf[6]; /* longest cmd is GTxxx */ switch (func) { @@ -1246,7 +1420,7 @@ int kenwood_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) case RIG_FUNC_LOCK: sprintf(buf, "LK%c", (status == 0) ? '0' : '1'); return kenwood_simple_cmd(rig, buf); - + case RIG_FUNC_AIP: sprintf(buf, "MX%c", (status == 0) ? '0' : '1'); return kenwood_simple_cmd(rig, buf); @@ -1259,13 +1433,17 @@ int kenwood_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) return -RIG_EINVAL; } -/* - * assumes status!=NULL +/* * works for any 'format 1' command * answer is always 4 bytes: two byte command id, status and terminator */ static int get_kenwood_func(RIG *rig, const char *cmd, int *status) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !cmd || !status) + return -RIG_EINVAL; + int retval; char buf[10]; @@ -1280,10 +1458,14 @@ static int get_kenwood_func(RIG *rig, const char *cmd, int *status) /* * kenwood_get_func - * Assumes rig!=NULL, val!=NULL */ int kenwood_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !status) + return -RIG_EINVAL; + char fctbuf[20]; int retval; @@ -1340,7 +1522,7 @@ int kenwood_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) /* * kenwood_set_ctcss_tone - * Assumes rig!=NULL, rig->caps->ctcss_list != NULL + * 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 @@ -1349,6 +1531,11 @@ int kenwood_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) */ int kenwood_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + const struct rig_caps *caps; char tonebuf[16]; int i; @@ -1365,12 +1552,17 @@ int kenwood_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) /* TODO: replace menu no 57 by a define */ sprintf(tonebuf, "EX%03d%04d", 57, i+1); - + return kenwood_simple_cmd(rig, tonebuf); } int kenwood_set_ctcss_tone_tn(RIG *rig, vfo_t vfo, tone_t tone) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + const struct rig_caps *caps = rig->caps; char buf[6]; int i; @@ -1391,16 +1583,21 @@ int kenwood_set_ctcss_tone_tn(RIG *rig, vfo_t vfo, tone_t tone) /* * kenwood_get_ctcss_tone - * Assumes rig!=NULL, rig->state.priv!=NULL + * Assumes rig->state.priv != NULL */ int kenwood_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !tone) + return -RIG_EINVAL; + struct kenwood_priv_data *priv = rig->state.priv; const struct rig_caps *caps; char tonebuf[3]; int i, retval; unsigned int tone_idx; - + caps = rig->caps; retval = kenwood_get_if(rig); @@ -1417,7 +1614,7 @@ int kenwood_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) __func__, tonebuf); return -RIG_EPROTO; } - + /* check this tone exists. That's better than nothing. */ for (i = 0; ictcss_list[i] == 0) { @@ -1436,6 +1633,11 @@ int kenwood_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) */ int kenwood_set_ant(RIG * rig, vfo_t vfo, ant_t ant) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + const char *cmd; switch (ant) { @@ -1460,6 +1662,11 @@ int kenwood_set_ant(RIG * rig, vfo_t vfo, ant_t ant) int kenwood_set_ant_no_ack(RIG * rig, vfo_t vfo, ant_t ant) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + const char *cmd; switch (ant) { @@ -1485,8 +1692,13 @@ int kenwood_set_ant_no_ack(RIG * rig, vfo_t vfo, ant_t ant) /* * get the aerial/antenna in use */ -int kenwood_get_ant (RIG * rig, vfo_t vfo, ant_t * ant) +int kenwood_get_ant (RIG *rig, vfo_t vfo, ant_t *ant) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !ant) + return -RIG_EINVAL; + char ackbuf[6]; int retval; @@ -1506,10 +1718,14 @@ int kenwood_get_ant (RIG * rig, vfo_t vfo, ant_t * ant) /* * kenwood_get_ptt - * Assumes rig!=NULL, ptt!=NULL */ int kenwood_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !ptt) + return -RIG_EINVAL; + struct kenwood_priv_data *priv = rig->state.priv; int retval; @@ -1525,23 +1741,31 @@ int kenwood_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) /* * kenwood_set_ptt - * Assumes rig!=NULL */ int kenwood_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { - return kenwood_simple_cmd(rig, - (ptt == RIG_PTT_ON) ? "TX" : "RX"); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + + return kenwood_simple_cmd(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX"); } int kenwood_set_ptt_safe(RIG *rig, vfo_t vfo, ptt_t ptt) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + int err; ptt_t current_ptt; - + err = kenwood_get_ptt(rig, vfo, ¤t_ptt); if (err != RIG_OK) return err; - + if (current_ptt == ptt) return RIG_OK; @@ -1552,13 +1776,17 @@ int kenwood_set_ptt_safe(RIG *rig, vfo_t vfo, ptt_t ptt) /* * kenwood_get_dcd - * Assumes rig!=NULL, dcd!=NULL */ int kenwood_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !dcd) + return -RIG_EINVAL; + char busybuf[10]; int retval; - + retval = kenwood_safe_transaction(rig, "BY", busybuf, 10, 4); if (retval != RIG_OK) return retval; @@ -1570,20 +1798,28 @@ int kenwood_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) /* * kenwood_set_trn - * Assumes rig!=NULL */ int kenwood_set_trn(RIG *rig, int trn) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + return kenwood_simple_transaction(rig, (trn == RIG_TRN_RIG) ? "AI1" : "AI0", 4); } /* * kenwood_get_trn - * Assumes rig!=NULL, trn!=NULL */ int kenwood_get_trn(RIG *rig, int *trn) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !trn) + return -RIG_EINVAL; + char trnbuf[6]; int retval; @@ -1598,20 +1834,28 @@ int kenwood_get_trn(RIG *rig, int *trn) /* * kenwood_set_powerstat - * Assumes rig!=NULL */ int kenwood_set_powerstat(RIG *rig, powerstat_t status) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + return kenwood_simple_transaction(rig, (status == RIG_POWER_ON) ? "PS1" : "PS0", 4); } /* * kenwood_get_powerstat - * Assumes rig!=NULL, trn!=NULL */ int kenwood_get_powerstat(RIG *rig, powerstat_t *status) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !status) + return -RIG_EINVAL; + char pwrbuf[6]; int retval; @@ -1626,10 +1870,14 @@ int kenwood_get_powerstat(RIG *rig, powerstat_t *status) /* * kenwood_reset - * Assumes rig!=NULL */ int kenwood_reset(RIG *rig, reset_t reset) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + char rstbuf[6]; char rst; @@ -1656,10 +1904,14 @@ int kenwood_reset(RIG *rig, reset_t reset) /* * kenwood_send_morse - * Assumes rig!=NULL */ int kenwood_send_morse(RIG *rig, vfo_t vfo, const char *msg) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !msg) + return -RIG_EINVAL; + char morsebuf[30], m2[30]; int msg_len, buff_len, retval; const char *p; @@ -1672,7 +1924,7 @@ int kenwood_send_morse(RIG *rig, vfo_t vfo, const char *msg) * TODO: check with "KY" if char buffer is available. * if not, sleep. * - * Make the total message segments 28 characters + * Make the total message segments 28 characters * in length because Kenwood demands it. * Spaces fill in the message end. */ @@ -1696,10 +1948,14 @@ int kenwood_send_morse(RIG *rig, vfo_t vfo, const char *msg) /* * kenwood_vfo_op - * Assumes rig!=NULL */ int kenwood_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_simple_cmd(rig, "UP"); @@ -1722,10 +1978,14 @@ int kenwood_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) /* * kenwood_set_mem - * Assumes rig!=NULL */ int kenwood_set_mem(RIG *rig, vfo_t vfo, int ch) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + char buf[8]; /* * "MCbmm;" @@ -1739,10 +1999,14 @@ int kenwood_set_mem(RIG *rig, vfo_t vfo, int ch) /* * kenwood_get_mem - * Assumes rig!=NULL */ int kenwood_get_mem(RIG *rig, vfo_t vfo, int *ch) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !ch) + return -RIG_EINVAL; + char membuf[10]; int retval; @@ -1763,6 +2027,11 @@ int kenwood_get_mem(RIG *rig, vfo_t vfo, int *ch) int kenwood_get_mem_if(RIG *rig, vfo_t vfo, int *ch) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !ch) + return -RIG_EINVAL; + int err; char buf[4]; struct kenwood_priv_data *priv = rig->state.priv; @@ -1781,6 +2050,11 @@ int kenwood_get_mem_if(RIG *rig, vfo_t vfo, int *ch) int kenwood_get_channel(RIG *rig, channel_t *chan) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !chan) + return -RIG_EINVAL; + int err; char buf[26]; char cmd[8]; @@ -1855,6 +2129,11 @@ int kenwood_get_channel(RIG *rig, channel_t *chan) int kenwood_set_channel(RIG *rig, const channel_t *chan) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !chan) + return -RIG_EINVAL; + char buf[26]; char mode, tx_mode = 0; int err; @@ -1863,19 +2142,19 @@ int kenwood_set_channel(RIG *rig, const channel_t *chan) struct kenwood_priv_caps *caps = kenwood_caps(rig); 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 (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; - } + if (tx_mode < 0 ) { + rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", + __func__, rig_strrmode(chan->tx_mode)); + return -RIG_EINVAL; + } } @@ -1916,6 +2195,11 @@ int kenwood_set_channel(RIG *rig, const channel_t *chan) int kenwood_set_ext_parm(RIG *rig, token_t token, value_t val) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return -RIG_EINVAL; + char buf[4]; switch (token) { @@ -1940,6 +2224,11 @@ int kenwood_set_ext_parm(RIG *rig, token_t token, value_t val) int kenwood_get_ext_parm(RIG *rig, token_t token, value_t *val) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !val) + return -RIG_EINVAL; + int err; struct kenwood_priv_data *priv = rig->state.priv; @@ -1970,10 +2259,14 @@ int kenwood_get_ext_parm(RIG *rig, token_t token, value_t *val) /* * kenwood_get_info * supposed to work only for TS2000... - * Assumes rig!=NULL */ const char* kenwood_get_info(RIG *rig) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig) + return "*rig == NULL"; + char firmbuf[10]; int retval; @@ -2001,10 +2294,12 @@ const char* kenwood_get_info(RIG *rig) */ DECLARE_PROBERIG_BACKEND(kenwood) { + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + char idbuf[IDBUFSZ]; int id_len=-1, i, k_id; int retval=-1; - int rates[] = { 115200, 57600, 9600, 4800, 1200, 0 }; /* possible baud rates */ + int rates[] = { 115200, 57600, 38400, 19200, 9600, 4800, 1200, 0 }; /* possible baud rates */ int rates_idx; if (!port) @@ -2023,11 +2318,11 @@ DECLARE_PROBERIG_BACKEND(kenwood) 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, "ID;", 3); id_len = read_string(port, idbuf, IDBUFSZ, ";\r", 2); close(port->fd); @@ -2039,7 +2334,7 @@ DECLARE_PROBERIG_BACKEND(kenwood) 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) { @@ -2074,11 +2369,11 @@ DECLARE_PROBERIG_BACKEND(kenwood) if (retval != RIG_OK) return RIG_MODEL_NONE; retval = write_block(port, "K2;", 3); - id_len = read_string(port, idbuf, IDBUFSZ, ";\r", 2); + id_len = read_string(port, idbuf, IDBUFSZ, ";\r", 2); close(port->fd); if (retval != RIG_OK) return RIG_MODEL_NONE; - /* + /* * reply should be something like 'K2n;' */ if (id_len == 4 || !strcmp(idbuf, "K2")) { @@ -2099,7 +2394,7 @@ DECLARE_PROBERIG_BACKEND(kenwood) } } /* - * not found in known table.... + * not found in known table.... * update kenwood_id_list[]! */ rig_debug(RIG_DEBUG_WARN, "probe_kenwood: found unknown device " @@ -2115,7 +2410,9 @@ DECLARE_PROBERIG_BACKEND(kenwood) */ DECLARE_INITRIG_BACKEND(kenwood) { - rig_debug(RIG_DEBUG_VERBOSE, "kenwood: _init called\n"); + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + +// rig_debug(RIG_DEBUG_VERBOSE, "kenwood: _init called\n"); rig_register(&ts950sdx_caps); rig_register(&ts50s_caps); @@ -2145,9 +2442,10 @@ DECLARE_INITRIG_BACKEND(kenwood) rig_register(&thf7e_caps); rig_register(&thg71_caps); rig_register(&tmv7_caps); - + + rig_register(&ts590_caps); rig_register(&ts590_caps); rig_register(&ts480_caps); - rig_register(&thf6a_caps); + rig_register(&thf6a_caps); return RIG_OK; } diff --git a/kenwood/kenwood.h b/kenwood/kenwood.h index e9fcaaad0..4d4ce35ea 100644 --- a/kenwood/kenwood.h +++ b/kenwood/kenwood.h @@ -30,7 +30,7 @@ #define EOM_TH '\r' #define KENWOOD_MODE_TABLE_MAX 10 -#define KENWOOD_MAX_BUF_LEN 50 /* max answer len, arbitrary */ +#define KENWOOD_MAX_BUF_LEN 50 /* max answer len, arbitrary */ #define TOK_VOICE TOKEN_BACKEND(1) #define TOK_FINE TOKEN_BACKEND(2)