Hamlib/rigs/yaesu/newcat.c

6352 wiersze
162 KiB
C
Czysty Zwykły widok Historia

/*
* hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net)
* and the Hamlib Group (hamlib-developer at lists.sourceforge.net)
*
* newcat.c - (C) Nate Bargmann 2007 (n0nb at arrl.net)
* (C) Stephane Fillod 2008-2010
* (C) Terry Embry 2008-2010
* (C) David Fannin (kk6df at arrl.net)
*
* This shared library provides an API for communicating
* via serial interface to any newer Yaesu radio using the
* "new" text CAT interface.
*
* Models this code aims to support are FTDX-9000*, FT-2000, FT-DX5000,
* FT-950, FT-450 and FT-1200. Much testing remains. -N0NB
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include "hamlib/rig.h"
#include "iofunc.h"
#include "serial.h"
#include "misc.h"
#include "newcat.h"
/* global variables */
static const char cat_term = ';'; /* Yaesu command terminator */
// static const char cat_unknown_cmd[] = "?;"; /* Yaesu ? */
/* Internal Backup and Restore VFO Memory Channels */
#define NC_MEM_CHANNEL_NONE 2012
#define NC_MEM_CHANNEL_VFO_A 2013
#define NC_MEM_CHANNEL_VFO_B 2014
/* ID 0310 == 310, Must drop leading zero */
2019-11-30 16:19:08 +00:00
typedef enum nc_rigid_e
{
NC_RIGID_NONE = 0,
NC_RIGID_FT450 = 241,
NC_RIGID_FT450D = 244,
NC_RIGID_FT950 = 310,
NC_RIGID_FT891 = 135,
NC_RIGID_FT991 = 135,
NC_RIGID_FT2000 = 251,
NC_RIGID_FT2000D = 252,
NC_RIGID_FT1200 = 583,
NC_RIGID_FTDX9000D = 101,
NC_RIGID_FTDX9000Contest = 102,
NC_RIGID_FTDX9000MP = 103,
2018-11-20 16:48:08 +00:00
NC_RIGID_FTDX5000 = 362,
2019-10-10 17:16:07 +00:00
NC_RIGID_FTDX3000 = 460,
NC_RIGID_FTDX101D = 681,
NC_RIGID_FTDX101MP = 682
} nc_rigid_t;
/*
* The following table defines which commands are valid for any given
* rig supporting the "new" CAT interface.
*/
2019-11-30 16:19:08 +00:00
typedef struct _yaesu_newcat_commands
{
char *command;
ncboolean ft450;
ncboolean ft950;
ncboolean ft891;
ncboolean ft991;
ncboolean ft2000;
ncboolean ft9000;
ncboolean ft5000;
ncboolean ft1200;
2018-11-20 16:48:08 +00:00
ncboolean ft3000;
2019-10-10 17:16:07 +00:00
ncboolean ft101;
} yaesu_newcat_commands_t;
/*
* Even thought this table does make a handy reference, it could be depreciated as it is not really needed.
* All of the CAT commands used in the newcat interface are available on the FT-950, FT-2000, FT-5000, and FT-9000.
* There are 5 CAT commands used in the newcat interface that are not available on the FT-450.
* Thesec CAT commands are XT -TX Clarifier ON/OFF, AN - Antenna select, PL - Speech Proc Level,
* PR - Speech Proc ON/OFF, and BC - Auto Notch filter ON/OFF.
* The FT-450 returns -RIG_ENVAIL for these unavailable CAT commands.
*
* NOTE: The following table must be in alphabetical order by the
* command. This is because it is searched using a binary search
* to determine whether or not a command is valid for a given rig.
*
* The list of supported commands is obtained from the rig's operator's
* or CAT programming manual.
*
*/
2019-11-30 16:19:08 +00:00
static const yaesu_newcat_commands_t valid_commands[] =
{
2020-03-15 20:32:46 +00:00
/* Command FT-450 FT-950 FT-891 FT-991 FT-2000 FT-9000 FT-5000 FT-1200 FT-3000 FTDX101D */
2019-10-10 17:16:07 +00:00
{"AB", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"AC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"AG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"AI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"AM", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"AN", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"AO", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
{"BA", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE },
{"BC", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"BD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"BI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"BM", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
{"BP", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"BS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"BU", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"BY", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"CH", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"CN", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"CO", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"CS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"CT", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"DA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"DN", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"DT", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE },
{"DP", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE },
{"DS", TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE },
{"ED", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"EK", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE },
{"EN", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE },
{"EU", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"EX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"FA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"FB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"FK", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE },
{"FR", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"FS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"FT", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"GT", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"ID", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"IF", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"IS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"KM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"KP", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"KR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"KS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"KY", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"LK", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"LM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"MA", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"MB", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
{"MC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"MD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"MG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"MK", TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE },
{"ML", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"MR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"MS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"MT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
{"MW", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"MX", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"NA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"NB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"NL", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"NR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"OI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"OS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"PA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"PB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"PC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"PL", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"PR", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"PS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"QI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"QR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"QS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RF", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RL", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RO", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE },
{"RP", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
{"RS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RT", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"RU", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"SC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"SD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"SF", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"SH", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"SM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"SQ", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"SS", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
{"ST", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
{"SV", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"SY", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
{"TS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
2020-03-07 04:34:05 +00:00
{"TX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
2019-10-10 17:16:07 +00:00
{"UL", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"UP", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"VD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"VF", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE },
{"VG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"VM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"VR", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
{"VS", TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"VT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
{"VV", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
{"VX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"XT", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE },
{"ZI", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE },
};
2019-11-30 16:19:08 +00:00
int valid_commands_count = sizeof(valid_commands) / sizeof(
yaesu_newcat_commands_t);
2019-11-30 16:19:08 +00:00
/*
* configuration Tokens
*
*/
#define TOK_FAST_SET_CMD TOKEN_BACKEND(1)
2019-11-30 16:19:08 +00:00
const struct confparams newcat_cfg_params[] =
{
{
TOK_FAST_SET_CMD, "fast_commands_token", "High troughput of commands", "Enabled high throughput of >200 messages/sec by not waiting for ACK/NAK of messages", "0", RIG_CONF_NUMERIC, { .n = { 0, 1, 1 } }
},
{ RIG_CONF_END, NULL, }
};
/* NewCAT Internal Functions */
2019-11-30 16:19:08 +00:00
static ncboolean newcat_is_rig(RIG *rig, rig_model_t model);
static int newcat_get_tx_vfo(RIG *rig, vfo_t *tx_vfo);
static int newcat_set_tx_vfo(RIG *rig, vfo_t tx_vfo);
2019-11-30 16:19:08 +00:00
static int newcat_set_vfo_from_alias(RIG *rig, vfo_t *vfo);
static int newcat_scale_float(int scale, float fval);
2019-11-30 16:19:08 +00:00
static int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode,
pbwidth_t *width);
static int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode,
pbwidth_t width);
static int newcat_set_narrow(RIG *rig, vfo_t vfo, ncboolean narrow);
static int newcat_get_narrow(RIG *rig, vfo_t vfo, ncboolean *narrow);
static int newcat_set_faststep(RIG *rig, ncboolean fast_step);
static int newcat_get_faststep(RIG *rig, ncboolean *fast_step);
static int newcat_get_rigid(RIG *rig);
static int newcat_get_vfo_mode(RIG *rig, vfo_t *vfo_mode);
static int newcat_vfomem_toggle(RIG *rig);
static ncboolean newcat_valid_command(RIG *rig, char const *const command);
/*
* ************************************
*
* Hamlib API functions
*
* ************************************
*/
/*
* rig_init
*
*/
2019-11-30 16:19:08 +00:00
int newcat_init(RIG *rig)
{
struct newcat_priv_data *priv;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2020-02-23 17:26:09 +00:00
rig->state.priv = (struct newcat_priv_data *) calloc(1,
sizeof(struct newcat_priv_data));
2019-11-30 16:19:08 +00:00
2020-01-13 18:48:30 +00:00
if (!rig->state.priv) /* whoops! memory shortage! */
2019-11-30 16:19:08 +00:00
{
return -RIG_ENOMEM;
2019-11-30 16:19:08 +00:00
}
2020-01-13 18:48:30 +00:00
priv = rig->state.priv;
/* TODO: read pacing from preferences */
// priv->pacing = NEWCAT_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */
2019-11-30 16:19:08 +00:00
priv->read_update_delay =
NEWCAT_DEFAULT_READ_TIMEOUT; /* set update timeout to safe value */
// priv->current_vfo = RIG_VFO_MAIN; /* default to whatever */
// priv->current_vfo = RIG_VFO_A;
priv->rig_id = NC_RIGID_NONE;
priv->current_mem = NC_MEM_CHANNEL_NONE;
priv->fast_set_commands = FALSE;
return RIG_OK;
}
/*
* rig_cleanup
*
* the serial port is closed by the frontend
*
*/
2019-11-30 16:19:08 +00:00
int newcat_cleanup(RIG *rig)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (rig->state.priv)
2019-11-30 16:19:08 +00:00
{
free(rig->state.priv);
2019-11-30 16:19:08 +00:00
}
rig->state.priv = NULL;
return RIG_OK;
}
/*
* rig_open
*
* New CAT does not support pacing
*
*/
2019-11-30 16:19:08 +00:00
int newcat_open(RIG *rig)
{
struct newcat_priv_data *priv = rig->state.priv;
struct rig_state *rig_s = &rig->state;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n",
2019-11-30 16:19:08 +00:00
__func__, rig_s->rigport.write_delay);
rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n",
2019-11-30 16:19:08 +00:00
__func__, rig_s->rigport.post_write_delay);
2019-12-23 04:23:57 +00:00
/* Ensure rig is powered on */
rig_set_powerstat(rig, 1);
/* get current AI state so it can be restored */
priv->trn_state = -1;
2019-11-30 16:19:08 +00:00
newcat_get_trn(rig, &priv->trn_state); /* ignore errors */
/* Currently we cannot cope with AI mode so turn it off in case
last client left it on */
newcat_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's
2019-11-30 16:19:08 +00:00
not supported */
/* Initialize rig_id in case any subsequent commands need it */
(void)newcat_get_rigid(rig);
2019-11-30 16:19:08 +00:00
return RIG_OK;
}
/*
* rig_close
*
*/
2019-11-30 16:19:08 +00:00
int newcat_close(RIG *rig)
{
2019-11-30 16:19:08 +00:00
struct newcat_priv_data *priv = rig->state.priv;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!no_restore_ai && priv->trn_state >= 0)
2019-11-30 16:19:08 +00:00
{
/* restore AI state */
2019-11-30 16:19:08 +00:00
newcat_set_trn(rig, priv->trn_state); /* ignore status in
case it's not
supported */
2019-11-30 16:19:08 +00:00
}
return RIG_OK;
}
/*
* rig_set_config
*
* Set Configuration Token for Yaesu Radios
*/
2019-11-30 16:19:08 +00:00
int newcat_set_conf(RIG *rig, token_t token, const char *val)
{
int ret = RIG_OK;
struct newcat_priv_data *priv;
2019-11-30 16:19:08 +00:00
priv = (struct newcat_priv_data *)rig->state.priv;
2019-11-30 16:19:08 +00:00
if (priv == NULL)
{
return -RIG_EINTERNAL;
}
2019-11-30 16:19:08 +00:00
switch (token)
{
char *end;
long value;
case TOK_FAST_SET_CMD: ;
2019-11-30 16:19:08 +00:00
//using strtol because atoi can lead to undefined behaviour
value = strtol(val, &end, 10);
if (end == val)
{
return -RIG_EINVAL;
}
if ((value == 0) || (value == 1))
{
priv->fast_set_commands = (int)value;
}
else
{
return -RIG_EINVAL;
}
break;
default:
2019-11-30 16:19:08 +00:00
ret = -RIG_EINVAL;
}
return ret;
}
/*
* rig_get_config
*
* Get Configuration Token for Yaesu Radios
*/
2019-11-30 16:19:08 +00:00
int newcat_get_conf(RIG *rig, token_t token, char *val)
{
int ret = RIG_OK;
struct newcat_priv_data *priv;
2019-11-30 16:19:08 +00:00
priv = (struct newcat_priv_data *)rig->state.priv;
2019-11-30 16:19:08 +00:00
if (priv == NULL)
{
return -RIG_EINTERNAL;
}
2019-11-30 16:19:08 +00:00
switch (token)
{
case TOK_FAST_SET_CMD:
2019-11-30 16:19:08 +00:00
if (sizeof(val) < 2)
{
return -RIG_ENOMEM;
}
sprintf(val, "%d", priv->fast_set_commands);
break;
2019-11-30 16:19:08 +00:00
default:
ret = -RIG_EINVAL;
}
return ret;
}
/*
* rig_set_freq
*
* Set frequency for a given VFO
* RIG_TARGETABLE_VFO
* Does not SET priv->current_vfo
*
*/
2019-11-30 16:19:08 +00:00
int newcat_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
{
char c;
char target_vfo;
int err;
const struct rig_caps *caps;
struct newcat_priv_data *priv;
int special_60m = 0;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "FA"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
priv = (struct newcat_priv_data *)rig->state.priv;
caps = rig->caps;
rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo));
// rig_debug(RIG_DEBUG_TRACE, "%s: translated vfo = %s\n", __func__, rig_strvfo(tvfo));
rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq);
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
/* vfo should now be modified to a valid VFO constant. */
/* DX3000/DX5000 can only do VFO_MEM on 60M */
/* So we will not change freq in that case */
special_60m = newcat_is_rig(rig, RIG_MODEL_FTDX3000);
/* duplicate the following line to add more rigs */
special_60m |= newcat_is_rig(rig, RIG_MODEL_FTDX5000);
2019-11-30 16:19:08 +00:00
switch (vfo)
{
case RIG_VFO_A:
c = 'A';
break;
case RIG_VFO_B:
c = 'B';
break;
case RIG_VFO_MEM:
if (special_60m && (freq >= 5300000 && freq <= 5410000))
{
rig_debug(RIG_DEBUG_TRACE, "%s: 60M VFO_MEM exception, no freq change done\n",
__func__);
return RIG_OK; /* make it look like we changed */
}
c = 'A';
break;
default:
return -RIG_ENIMPL; /* Only VFO_A or VFO_B are valid */
}
target_vfo = 'A' == c ? '0' : '1';
2019-11-30 16:19:08 +00:00
if (RIG_MODEL_FT450 == caps->rig_model)
2019-11-30 16:19:08 +00:00
{
/* The FT450 only accepts F[A|B]nnnnnnnn; commands for the
current VFO so we must use the VS[0|1]; command to check
and select the correct VFO before setting the frequency
*/
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VS%c", cat_term);
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
if (priv->ret_data[2] != target_vfo)
2019-11-30 16:19:08 +00:00
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VS%c%c", target_vfo, cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_set_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
}
}
// W1HKJ
// creation of the priv structure guarantees that the string can be NEWCAT_DATA_LEN
// bytes in length. the snprintf will only allow (NEWCAT_DATA_LEN - 1) chars
// followed by the NULL terminator.
// CAT command string for setting frequency requires that 8 digits be sent
// including leading fill zeros
// Call this after open to set width_frequency for later use
2019-11-30 16:19:08 +00:00
if (priv->width_frequency == 0)
{
vfo_t vfo_mode;
newcat_get_vfo_mode(rig, &vfo_mode);
}
2020-03-23 12:52:01 +00:00
// cppcheck-suppress *
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "F%c%0*"PRIll"%c", c,
priv->width_frequency, (int64_t)freq, cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s:%d cmd_str = %s\n", __func__, __LINE__,
priv->cmd_str);
if (RIG_OK != (err = newcat_set_cmd(rig)))
2019-11-30 16:19:08 +00:00
{
rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__,
err);
return err;
2019-11-30 16:19:08 +00:00
}
if (RIG_MODEL_FT450 == caps->rig_model && priv->ret_data[2] != target_vfo)
2019-11-30 16:19:08 +00:00
{
/* revert current VFO */
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s:%d cmd_str = %s\n", __func__, __LINE__,
priv->ret_data);
if (RIG_OK != (err = newcat_set_cmd(rig)))
2019-11-30 16:19:08 +00:00
{
rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__,
err);
return err;
2019-11-30 16:19:08 +00:00
}
}
return RIG_OK;
}
/*
* rig_get_freq
*
* Return Freq for a given VFO
* RIG_TARGETABLE_FREQ
* Does not SET priv->current_vfo
*
*/
2019-11-30 16:19:08 +00:00
int newcat_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
{
char command[3];
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
char c;
int err;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo));
if (!newcat_valid_command(rig, "FA"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
switch (vfo)
{
case RIG_VFO_A:
c = 'A';
break;
case RIG_VFO_B:
c = 'B';
break;
case RIG_VFO_MEM:
c = 'A';
break;
default:
return -RIG_EINVAL; /* sorry, unsupported VFO */
}
/* Build the command string */
snprintf(command, sizeof(command), "F%c", c);
2019-11-30 16:19:08 +00:00
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term);
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str);
/* get freq */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
/* convert the read frequency string into freq_t and store in *freq */
2019-11-30 16:19:08 +00:00
sscanf(priv->ret_data + 2, "%"SCNfreq, freq);
rig_debug(RIG_DEBUG_TRACE,
2019-11-30 16:19:08 +00:00
"%s: freq = %"PRIfreq" Hz for vfo %s\n", __func__, *freq, rig_strvfo(vfo));
return RIG_OK;
}
int newcat_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
{
struct newcat_priv_data *priv;
int err;
priv = (struct newcat_priv_data *)rig->state.priv;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "MD"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MD0x%c", cat_term);
/* FT9000 RIG_TARGETABLE_MODE (mode and width) */
/* FT2000 mode only */
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
2019-11-30 16:19:08 +00:00
{
priv->cmd_str[2] = (RIG_VFO_B == vfo) ? '1' : '0';
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s \n",
__func__, rig_strrmode(mode));
2019-11-30 16:19:08 +00:00
switch (mode)
{
case RIG_MODE_LSB:
priv->cmd_str[3] = '1';
break;
case RIG_MODE_USB:
priv->cmd_str[3] = '2';
break;
case RIG_MODE_CW:
priv->cmd_str[3] = '3';
break;
2020-01-15 14:15:29 +00:00
case RIG_MODE_FM:
priv->cmd_str[3] = '4';
break;
2019-11-30 16:19:08 +00:00
case RIG_MODE_AM:
priv->cmd_str[3] = '5';
break;
case RIG_MODE_RTTY:
priv->cmd_str[3] = '6';
break;
case RIG_MODE_CWR:
priv->cmd_str[3] = '7';
break;
case RIG_MODE_PKTLSB: /* FT450 USER-L */
priv->cmd_str[3] = '8';
break;
case RIG_MODE_RTTYR:
priv->cmd_str[3] = '9';
break;
case RIG_MODE_PKTFM:
priv->cmd_str[3] = 'A';
break;
2020-01-15 14:15:29 +00:00
case RIG_MODE_FMN:
priv->cmd_str[3] = 'B';
2019-11-30 16:19:08 +00:00
break;
case RIG_MODE_PKTUSB: /* FT450 USER-U */
priv->cmd_str[3] = 'C';
break;
2020-02-23 17:26:09 +00:00
case RIG_MODE_AMN:
2020-01-15 14:22:35 +00:00
priv->cmd_str[3] = 'D';
break;
2020-02-23 17:26:09 +00:00
case RIG_MODE_C4FM:
2020-01-15 14:22:35 +00:00
priv->cmd_str[3] = 'E';
break;
2019-11-30 16:19:08 +00:00
default:
return -RIG_EINVAL;
}
err = newcat_set_cmd(rig);
2019-11-30 16:19:08 +00:00
if (err != RIG_OK)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (RIG_PASSBAND_NOCHANGE == width) { return err; }
if (RIG_PASSBAND_NORMAL == width)
2019-11-30 16:19:08 +00:00
{
width = rig_passband_normal(rig, mode);
2019-11-30 16:19:08 +00:00
}
/* Set width after mode has been set */
err = newcat_set_rx_bandwidth(rig, vfo, mode, width);
return err;
}
int newcat_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
char c;
int err;
ncboolean narrow;
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "MD"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
2019-11-30 16:19:08 +00:00
{
main_sub_vfo = RIG_VFO_B == vfo ? '1' : '0';
2019-11-30 16:19:08 +00:00
}
/* Build the command string */
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MD%c%c", main_sub_vfo,
cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
/* Get MODE */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
/*
* The current mode value is a digit '0' ... 'C'
* embedded at ret_data[3] in the read string.
*/
c = priv->ret_data[3];
/* default, unless set otherwise */
*width = RIG_PASSBAND_NORMAL;
2019-11-30 16:19:08 +00:00
switch (c)
{
case '1':
*mode = RIG_MODE_LSB;
2019-11-30 16:19:08 +00:00
break;
2019-11-30 16:19:08 +00:00
case '2':
*mode = RIG_MODE_USB;
2019-11-30 16:19:08 +00:00
break;
case '3':
*mode = RIG_MODE_CW;
break;
case '4':
*mode = RIG_MODE_FM;
err = newcat_get_narrow(rig, vfo, &narrow);
if (narrow == TRUE)
{
*width = rig_passband_narrow(rig, *mode);
}
else
{
*width = rig_passband_normal(rig, *mode);
}
return err;
case '5':
*mode = RIG_MODE_AM;
err = newcat_get_narrow(rig, vfo, &narrow);
if (narrow == TRUE)
{
*width = rig_passband_narrow(rig, *mode);
}
else
{
*width = rig_passband_normal(rig, *mode);
}
return err;
case '6':
*mode = RIG_MODE_RTTY;
break;
case '7':
*mode = RIG_MODE_CWR;
break;
case '8':
*mode = RIG_MODE_PKTLSB; /* FT450 USER-L */
break;
case '9':
*mode = RIG_MODE_RTTYR;
break;
case 'A':
*mode = RIG_MODE_PKTFM;
err = newcat_get_narrow(rig, vfo, &narrow);
if (narrow == TRUE)
{
*width = rig_passband_narrow(rig, *mode);
}
else
{
*width = rig_passband_normal(rig, *mode);
}
return err;
case 'B':
2020-01-15 14:15:29 +00:00
*mode = RIG_MODE_FMN; /* narrow */
2019-11-30 16:19:08 +00:00
*width = rig_passband_narrow(rig, *mode);
return RIG_OK;
case 'C':
*mode = RIG_MODE_PKTUSB; /* FT450 USER-U */
break;
case 'D':
*mode = RIG_MODE_AM; /* narrow, FT950 */
*width = rig_passband_narrow(rig, *mode);
return RIG_OK;
2020-01-15 14:15:29 +00:00
case 'E':
*mode = RIG_MODE_C4FM; /* narrow, FT950 */
*width = rig_passband_narrow(rig, *mode);
return RIG_OK;
2019-11-30 16:19:08 +00:00
default:
return -RIG_EPROTO;
}
if (RIG_PASSBAND_NORMAL == *width)
{
*width = rig_passband_normal(rig, *mode);
}
return newcat_get_rx_bandwidth(rig, vfo, *mode, width);
}
/*
* rig_set_vfo
*
* set vfo and store requested vfo for later RIG_VFO_CURR
* requests.
*
*/
int newcat_set_vfo(RIG *rig, vfo_t vfo)
{
struct newcat_priv_data *priv;
struct rig_state *state;
char c;
int err, mem;
vfo_t vfo_mode;
char command[] = "VS";
priv = (struct newcat_priv_data *)rig->state.priv;
state = &rig->state;
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: called, passed vfo = %s\n", __func__,
rig_strvfo(vfo));
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
err = newcat_set_vfo_from_alias(rig,
&vfo); /* passes RIG_VFO_MEM, RIG_VFO_A, RIG_VFO_B */
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
switch (vfo)
{
case RIG_VFO_A:
case RIG_VFO_B:
if (vfo == RIG_VFO_B)
{
c = '1';
}
else
{
c = '0';
}
err = newcat_get_vfo_mode(rig, &vfo_mode);
2020-02-23 17:26:09 +00:00
if (err != RIG_OK)
{
return err;
}
2019-11-30 16:19:08 +00:00
if (vfo_mode == RIG_VFO_MEM)
{
priv->current_mem = NC_MEM_CHANNEL_NONE;
state->current_vfo = RIG_VFO_A;
err = newcat_vfomem_toggle(rig);
return err;
}
break;
case RIG_VFO_MEM:
if (priv->current_mem == NC_MEM_CHANNEL_NONE)
{
/* Only works correctly for VFO A */
if (state->current_vfo == RIG_VFO_B)
{
return -RIG_ENTARGET;
}
/* get current memory channel */
err = newcat_get_mem(rig, vfo, &mem);
2019-11-30 16:19:08 +00:00
if (err != RIG_OK)
{
return err;
}
2019-11-30 16:19:08 +00:00
/* turn on memory channel */
err = newcat_set_mem(rig, vfo, mem);
if (err != RIG_OK)
{
return err;
}
2019-11-30 16:19:08 +00:00
/* Set current_mem now */
priv->current_mem = mem;
}
/* Set current_vfo now */
state->current_vfo = vfo;
return RIG_OK;
default:
return -RIG_ENIMPL; /* sorry, VFO not implemented */
}
/* Build the command string */
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, c, cat_term);
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str);
err = newcat_set_cmd(rig);
2019-11-30 16:19:08 +00:00
if (err != RIG_OK)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
state->current_vfo = vfo; /* if set_vfo worked, set current_vfo */
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: rig->state.current_vfo = %s\n", __func__,
rig_strvfo(vfo));
return RIG_OK;
}
/*
* rig_get_vfo
*
* get current RX vfo/mem and store requested vfo for
* later RIG_VFO_CURR requests plus pass the tested vfo/mem
* back to the frontend.
*
*/
2019-11-30 16:19:08 +00:00
int newcat_get_vfo(RIG *rig, vfo_t *vfo)
{
struct rig_state *state = &rig->state;
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
vfo_t vfo_mode;
2019-11-30 16:19:08 +00:00
char const *command = "VS";
if (!vfo)
2019-11-30 16:19:08 +00:00
{
return -RIG_EINVAL;
2019-11-30 16:19:08 +00:00
}
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
/* Build the command string */
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s;", command);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
/* Get VFO */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
/*
* The current VFO value is a digit ('0' or '1' ('A' or 'B'
* respectively)) embedded at ret_data[2] in the read string.
*/
switch (priv->ret_data[2])
2019-11-30 16:19:08 +00:00
{
case '0':
*vfo = RIG_VFO_A;
break;
2019-11-30 16:19:08 +00:00
case '1':
*vfo = RIG_VFO_B;
break;
2019-11-30 16:19:08 +00:00
default:
return -RIG_EPROTO; /* sorry, wrong current VFO */
2019-11-30 16:19:08 +00:00
}
/* Check to see if RIG is in MEM mode */
err = newcat_get_vfo_mode(rig, &vfo_mode);
2020-02-23 17:26:09 +00:00
if (err != RIG_OK)
{
return err;
}
2019-11-30 16:19:08 +00:00
if (vfo_mode == RIG_VFO_MEM)
2019-11-30 16:19:08 +00:00
{
*vfo = RIG_VFO_MEM;
2019-11-30 16:19:08 +00:00
}
state->current_vfo = *vfo; /* set now */
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: rig->state.current_vfo = %s\n", __func__,
rig_strvfo(state->current_vfo));
return RIG_OK;
}
int newcat_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char txon[] = "TX1;";
char txoff[] = "TX0;";
if (!newcat_valid_command(rig, "TX"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
switch (ptt)
{
case RIG_PTT_ON:
/* Build the command string */
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s", txon);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
err = newcat_set_cmd(rig);
break;
case RIG_PTT_OFF:
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s", txoff);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
err = newcat_set_cmd(rig);
break;
default:
return -RIG_EINVAL;
}
2019-11-30 16:19:08 +00:00
return err;
}
2019-11-30 16:19:08 +00:00
int newcat_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
char c;
int err;
if (!newcat_valid_command(rig, "TX"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", "TX", cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
/* Get PTT */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
c = priv->ret_data[2];
2019-11-30 16:19:08 +00:00
switch (c)
{
case '0': /* FT-950 "TX OFF", Original Release Firmware */
*ptt = RIG_PTT_OFF;
break;
case '1' : /* Just because,    what the CAT Manual Shows */
case '2' : /* FT-950 Radio:    Mic, Dataport, CW "TX ON" */
case '3' : /* FT-950 CAT port: Radio in "TX ON" mode     [Not what the CAT Manual Shows] */
*ptt = RIG_PTT_ON;
break;
default:
return -RIG_EPROTO;
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char c;
char command[] = "OS";
char main_sub_vfo = '0';
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
/* Main or SUB vfo */
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
2019-11-30 16:19:08 +00:00
{
main_sub_vfo = RIG_VFO_B == vfo ? '1' : '0';
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
switch (rptr_shift)
{
case RIG_RPT_SHIFT_NONE:
c = '0';
break;
case RIG_RPT_SHIFT_PLUS:
c = '1';
break;
case RIG_RPT_SHIFT_MINUS:
c = '2';
break;
default:
return -RIG_EINVAL;
}
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c%c", command,
main_sub_vfo, c, cat_term);
return newcat_set_cmd(rig);
}
2019-11-30 16:19:08 +00:00
int newcat_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char c;
char command[] = "OS";
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
/* Set Main or SUB vfo */
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
2019-11-30 16:19:08 +00:00
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
2019-11-30 16:19:08 +00:00
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, main_sub_vfo,
cat_term);
/* Get Rptr Shift */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
c = priv->ret_data[3];
2019-11-30 16:19:08 +00:00
switch (c)
{
case '0':
*rptr_shift = RIG_RPT_SHIFT_NONE;
break;
case '1':
*rptr_shift = RIG_RPT_SHIFT_PLUS;
break;
case '2':
*rptr_shift = RIG_RPT_SHIFT_MINUS;
break;
default:
return -RIG_EINVAL;
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode,
pbwidth_t tx_width)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode,
pbwidth_t *tx_width)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
{
int err;
vfo_t rx_vfo;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (newcat_is_rig(rig, RIG_MODEL_FT991))
2019-11-30 16:19:08 +00:00
{
vfo = RIG_VFO_A;
tx_vfo = RIG_SPLIT_ON == split ? RIG_VFO_B : RIG_VFO_A;
2019-11-30 16:19:08 +00:00
}
else
2019-11-30 16:19:08 +00:00
{
err = newcat_get_vfo(rig, &rx_vfo); /* sync to rig current vfo */
2019-11-30 16:19:08 +00:00
if (err != RIG_OK)
2019-11-30 16:19:08 +00:00
{
return err;
}
}
2019-11-30 16:19:08 +00:00
switch (split)
{
case RIG_SPLIT_OFF:
err = newcat_set_tx_vfo(rig, vfo);
if (err != RIG_OK)
{
return err;
}
if (rx_vfo != vfo && newcat_valid_command(rig, "VS"))
{
err = newcat_set_vfo(rig, vfo);
if (err != RIG_OK)
2019-11-30 16:19:08 +00:00
{
return err;
}
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
break;
2019-11-30 16:19:08 +00:00
case RIG_SPLIT_ON:
err = newcat_set_tx_vfo(rig, tx_vfo);
2019-11-30 16:19:08 +00:00
if (err != RIG_OK)
{
return err;
}
2019-11-30 16:19:08 +00:00
if (rx_vfo != vfo)
{
err = newcat_set_vfo(rig, vfo);
if (err != RIG_OK && err != -RIG_ENAVAIL)
{
return err;
}
}
break;
default:
return -RIG_EINVAL;
}
return RIG_OK;
}
int newcat_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo)
{
int err;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
err = newcat_set_vfo_from_alias(rig, &vfo);
if (err != RIG_OK)
{
return err;
}
err = newcat_get_tx_vfo(rig, tx_vfo);
2019-11-30 16:19:08 +00:00
if (err != RIG_OK)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (*tx_vfo != vfo)
2019-11-30 16:19:08 +00:00
{
*split = RIG_SPLIT_ON;
2019-11-30 16:19:08 +00:00
}
else
2019-11-30 16:19:08 +00:00
{
*split = RIG_SPLIT_OFF;
2019-11-30 16:19:08 +00:00
}
2020-03-26 16:11:46 +00:00
rig_debug(RIG_DEBUG_TRACE, "SPLIT = %d, vfo = %s, TX_vfo = %s\n", *split,
rig_strvfo(vfo),
2020-03-20 12:51:32 +00:00
rig_strvfo(*tx_vfo));
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
if (!newcat_valid_command(rig, "RT"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
if (rit > rig->caps->max_rit)
2019-11-30 16:19:08 +00:00
{
rit = rig->caps->max_rit; /* + */
}
else if (labs(rit) > rig->caps->max_rit)
2019-11-30 16:19:08 +00:00
{
rit = - rig->caps->max_rit; /* - */
}
if (rit == 0)
2019-11-30 16:19:08 +00:00
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRT0%c", cat_term,
cat_term);
}
else if (rit < 0)
2019-11-30 16:19:08 +00:00
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRD%04ld%cRT1%c", cat_term,
labs(rit), cat_term, cat_term);
}
else
2019-11-30 16:19:08 +00:00
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRU%04ld%cRT1%c", cat_term,
labs(rit), cat_term, cat_term);
}
return newcat_set_cmd(rig);
}
2019-11-30 16:19:08 +00:00
int newcat_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
char *retval;
char rit_on;
int err;
int offset = 0;
if (!newcat_valid_command(rig, "IF"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
*rit = 0;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", "IF", cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
/* Get RIT */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
// e.g. FT450 has 27 byte IF response, FT991 has 28 byte if response (one more byte for P2 VFO A Freq)
// so we now check to ensure we know the length of the response
2019-11-30 16:19:08 +00:00
switch (strlen(priv->ret_data))
{
case 27: offset = 13; break;
case 28: offset = 14; break;
default: offset = 0;
}
2019-11-30 16:19:08 +00:00
if (offset == 0)
{
rig_debug(RIG_DEBUG_ERR,
"%s: incorrect length of IF response, expected 27 or 28, got %du", __func__,
(int)strlen(priv->ret_data));
return -RIG_EPROTO;
}
retval = priv->ret_data + offset;
rit_on = retval[5];
retval[5] = '\0';
if (rit_on == '1')
2019-11-30 16:19:08 +00:00
{
*rit = (shortfreq_t) atoi(retval);
2019-11-30 16:19:08 +00:00
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
if (!newcat_valid_command(rig, "XT"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
if (xit > rig->caps->max_xit)
2019-11-30 16:19:08 +00:00
{
xit = rig->caps->max_xit; /* + */
}
else if (labs(xit) > rig->caps->max_xit)
2019-11-30 16:19:08 +00:00
{
xit = - rig->caps->max_xit; /* - */
}
if (xit == 0)
2019-11-30 16:19:08 +00:00
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cXT0%c", cat_term,
cat_term);
}
else if (xit < 0)
2019-11-30 16:19:08 +00:00
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRD%04ld%cXT1%c", cat_term,
labs(xit), cat_term, cat_term);
}
else
2019-11-30 16:19:08 +00:00
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRU%04ld%cXT1%c", cat_term,
labs(xit), cat_term, cat_term);
}
return newcat_set_cmd(rig);
}
2019-11-30 16:19:08 +00:00
int newcat_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
char *retval;
char xit_on;
int err;
int offset = 0;
if (!newcat_valid_command(rig, "IF"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
*xit = 0;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", "IF", cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
/* Get XIT */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
// e.g. FT450 has 27 byte IF response, FT991 has 28 byte if response (one more byte for P2 VFO A Freq)
// so we now check to ensure we know the length of the response
2019-11-30 16:19:08 +00:00
switch (strlen(priv->ret_data))
{
case 27: offset = 13; break;
case 28: offset = 14; break;
default: offset = 0;
}
2019-11-30 16:19:08 +00:00
if (offset == 0)
{
rig_debug(RIG_DEBUG_ERR,
"%s: incorrect length of IF response, expected 27 or 28, got %du", __func__,
(int)strlen(priv->ret_data));
return -RIG_EPROTO;
}
retval = priv->ret_data + offset;
xit_on = retval[6];
retval[5] = '\0';
if (xit_on == '1')
2019-11-30 16:19:08 +00:00
{
*xit = (shortfreq_t) atoi(retval);
2019-11-30 16:19:08 +00:00
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts)
{
int err, i;
pbwidth_t width;
rmode_t mode;
ncboolean ts_match;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
err = newcat_get_mode(rig, vfo, &mode, &width);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
/* assume 2 tuning steps per mode */
2019-11-30 16:19:08 +00:00
for (i = 0, ts_match = FALSE; i < TSLSTSIZ
&& rig->caps->tuning_steps[i].ts; i++)
if (rig->caps->tuning_steps[i].modes & mode)
{
if (ts <= rig->caps->tuning_steps[i].ts)
2019-11-30 16:19:08 +00:00
{
err = newcat_set_faststep(rig, FALSE);
2019-11-30 16:19:08 +00:00
}
else
2019-11-30 16:19:08 +00:00
{
err = newcat_set_faststep(rig, TRUE);
2019-11-30 16:19:08 +00:00
}
if (err != RIG_OK)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
ts_match = TRUE;
break;
} /* if mode */
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "ts_match = %d, i = %d, ts = %d\n", ts_match, i,
(int)ts);
if (ts_match)
2019-11-30 16:19:08 +00:00
{
return RIG_OK;
2019-11-30 16:19:08 +00:00
}
else
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
}
2019-11-30 16:19:08 +00:00
int newcat_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts)
{
pbwidth_t width;
rmode_t mode;
int err, i;
ncboolean ts_match;
ncboolean fast_step = FALSE;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
err = newcat_get_mode(rig, vfo, &mode, &width);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
err = newcat_get_faststep(rig, &fast_step);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
/* assume 2 tuning steps per mode */
2019-11-30 16:19:08 +00:00
for (i = 0, ts_match = FALSE; i < TSLSTSIZ
&& rig->caps->tuning_steps[i].ts; i++)
if (rig->caps->tuning_steps[i].modes & mode)
{
if (fast_step == FALSE)
2019-11-30 16:19:08 +00:00
{
*ts = rig->caps->tuning_steps[i].ts;
2019-11-30 16:19:08 +00:00
}
else
2019-11-30 16:19:08 +00:00
{
*ts = rig->caps->tuning_steps[i + 1].ts;
}
ts_match = TRUE;
break;
}
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "ts_match = %d, i = %d, i+1 = %d, *ts = %d\n",
ts_match, i, i + 1, (int)*ts);
if (ts_match)
2019-11-30 16:19:08 +00:00
{
return RIG_OK;
2019-11-30 16:19:08 +00:00
}
else
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
}
2019-11-30 16:19:08 +00:00
int newcat_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_set_tone(RIG *rig, vfo_t vfo, tone_t tone)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_get_tone(RIG *rig, vfo_t vfo, tone_t *tone)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
int i;
ncboolean tone_match;
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "CN"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
if (!newcat_valid_command(rig, "CT"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
2019-11-30 16:19:08 +00:00
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
2019-11-30 16:19:08 +00:00
}
for (i = 0, tone_match = FALSE; rig->caps->ctcss_list[i] != 0; i++)
2019-11-30 16:19:08 +00:00
if (tone == rig->caps->ctcss_list[i])
{
tone_match = TRUE;
break;
}
2020-03-20 12:51:32 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: tone = %u, tone_match = %d, i = %d", __func__,
2019-11-30 16:19:08 +00:00
tone, tone_match, i);
if (tone_match == FALSE && tone != 0)
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
if (tone == 0) /* turn off ctcss */
2019-11-30 16:19:08 +00:00
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CT%c0%c", main_sub_vfo,
cat_term);
}
else
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CN%c%02d%cCT%c2%c",
main_sub_vfo, i, cat_term, main_sub_vfo, cat_term);
}
return newcat_set_cmd(rig);
}
2019-11-30 16:19:08 +00:00
int newcat_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
int t;
int ret_data_len;
char *retlvl;
char cmd[] = "CN";
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, cmd))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
2019-11-30 16:19:08 +00:00
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo,
cat_term);
/* Get CTCSS TONE */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
ret_data_len = strlen(priv->ret_data);
/* skip command */
2019-11-30 16:19:08 +00:00
retlvl = priv->ret_data + strlen(priv->cmd_str) - 1;
/* chop term */
2019-11-30 16:19:08 +00:00
priv->ret_data[ret_data_len - 1] = '\0';
t = atoi(retlvl); /* tone index */
if (t < 0 || t > 49)
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
*tone = rig->caps->ctcss_list[t];
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_set_tone_sql(RIG *rig, vfo_t vfo, tone_t tone)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_get_tone_sql(RIG *rig, vfo_t vfo, tone_t *tone)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
int newcat_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone)
{
int err;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
err = newcat_set_ctcss_tone(rig, vfo, tone);
2019-11-30 16:19:08 +00:00
if (err != RIG_OK)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
/* Change to sql */
2019-11-30 16:19:08 +00:00
if (tone)
{
err = newcat_set_func(rig, vfo, RIG_FUNC_TSQL, TRUE);
2019-11-30 16:19:08 +00:00
if (err != RIG_OK)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone)
{
int err;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
err = newcat_get_ctcss_tone(rig, vfo, tone);
return err;
}
2019-11-30 16:19:08 +00:00
int newcat_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq,
rmode_t mode)
{
int rig_id;
rig_id = newcat_get_rigid(rig);
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2019-11-30 16:19:08 +00:00
switch (rig_id)
{
case NC_RIGID_FT450:
/* 100 Watts */
*mwpower = power * 100000;
2020-03-20 12:51:32 +00:00
rig_debug(RIG_DEBUG_TRACE, "case FT450 - rig_id = %d, *mwpower = %u\n", rig_id,
2019-11-30 16:19:08 +00:00
*mwpower);
break;
case NC_RIGID_FT950:
/* 100 Watts */
*mwpower = power * 100000; /* 0..100 Linear scale */
rig_debug(RIG_DEBUG_TRACE,
2020-03-20 12:51:32 +00:00
"case FT950 - rig_id = %d, power = %f, *mwpower = %u\n", rig_id, power,
2019-11-30 16:19:08 +00:00
*mwpower);
break;
case NC_RIGID_FT2000:
/* 100 Watts */
*mwpower = power * 100000;
2020-03-20 12:51:32 +00:00
rig_debug(RIG_DEBUG_TRACE, "case FT2000 - rig_id = %d, *mwpower = %u\n", rig_id,
2019-11-30 16:19:08 +00:00
*mwpower);
break;
case NC_RIGID_FT2000D:
/* 200 Watts */
*mwpower = power * 200000;
2020-03-20 12:51:32 +00:00
rig_debug(RIG_DEBUG_TRACE, "case FT2000D - rig_id = %d, *mwpower = %u\n",
2019-11-30 16:19:08 +00:00
rig_id, *mwpower);
break;
case NC_RIGID_FTDX5000:
/* 200 Watts */
*mwpower = power * 200000;
2020-03-20 12:51:32 +00:00
rig_debug(RIG_DEBUG_TRACE, "case FTDX5000 - rig_id = %d, *mwpower = %u\n",
2019-11-30 16:19:08 +00:00
rig_id, *mwpower);
break;
case NC_RIGID_FTDX9000D:
/* 200 Watts */
*mwpower = power * 200000;
2020-03-20 12:51:32 +00:00
rig_debug(RIG_DEBUG_TRACE, "case FTDX9000D - rig_id = %d, *mwpower = %u\n",
2019-11-30 16:19:08 +00:00
rig_id, *mwpower);
break;
case NC_RIGID_FTDX9000Contest:
/* 200 Watts */
*mwpower = power * 200000;
rig_debug(RIG_DEBUG_TRACE,
2020-03-20 12:51:32 +00:00
"case FTDX9000Contest - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower);
2019-11-30 16:19:08 +00:00
break;
case NC_RIGID_FTDX9000MP:
/* 400 Watts */
*mwpower = power * 400000;
2020-03-20 12:51:32 +00:00
rig_debug(RIG_DEBUG_TRACE, "case FTDX9000MP - rig_id = %d, *mwpower = %u\n",
2019-11-30 16:19:08 +00:00
rig_id, *mwpower);
break;
case NC_RIGID_FT1200:
/* 100 Watts */
*mwpower = power * 100000;
rig_debug(RIG_DEBUG_TRACE, "case FT1200 - rig_id = %d, *mwpower = %d\n", rig_id,
*mwpower);
break;
default:
/* 100 Watts */
*mwpower = power * 100000;
2020-03-20 12:51:32 +00:00
rig_debug(RIG_DEBUG_TRACE, "default - rig_id = %d, *mwpower = %u\n", rig_id,
2019-11-30 16:19:08 +00:00
*mwpower);
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq,
rmode_t mode)
{
int rig_id;
rig_id = newcat_get_rigid(rig);
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2019-11-30 16:19:08 +00:00
switch (rig_id)
{
case NC_RIGID_FT450:
/* 100 Watts */
*power = mwpower / 100000.0;
rig_debug(RIG_DEBUG_TRACE, "case FT450 - rig_id = %d, *power = %f\n", rig_id,
*power);
break;
case NC_RIGID_FT950:
/* 100 Watts */
*power = mwpower / 100000.0; /* 0..100 Linear scale */
rig_debug(RIG_DEBUG_TRACE,
2020-03-20 12:51:32 +00:00
"case FT950 - rig_id = %d, mwpower = %u, *power = %f\n", rig_id, mwpower,
2019-11-30 16:19:08 +00:00
*power);
break;
case NC_RIGID_FT2000:
/* 100 Watts */
*power = mwpower / 100000.0;
rig_debug(RIG_DEBUG_TRACE, "case FT2000 - rig_id = %d, *power = %f\n", rig_id,
*power);
break;
case NC_RIGID_FT2000D:
/* 200 Watts */
*power = mwpower / 200000.0;
rig_debug(RIG_DEBUG_TRACE, "case FT2000D - rig_id = %d, *power = %f\n", rig_id,
*power);
break;
case NC_RIGID_FTDX5000:
/* 200 Watts */
*power = mwpower / 200000.0;
rig_debug(RIG_DEBUG_TRACE, "case FTDX5000 - rig_id = %d, *power = %f\n", rig_id,
*power);
break;
case NC_RIGID_FTDX9000D:
/* 200 Watts */
*power = mwpower / 200000.0;
rig_debug(RIG_DEBUG_TRACE, "case FTDX9000D - rig_id = %d, *power = %f\n",
rig_id, *power);
break;
case NC_RIGID_FTDX9000Contest:
/* 200 Watts */
*power = mwpower / 200000.0;
rig_debug(RIG_DEBUG_TRACE, "case FTDX9000Contest - rig_id = %d, *power = %f\n",
rig_id, *power);
break;
case NC_RIGID_FTDX9000MP:
/* 400 Watts */
*power = mwpower / 400000.0;
rig_debug(RIG_DEBUG_TRACE, "case FTDX9000MP - rig_id = %d, *power = %f\n",
rig_id, *power);
break;
case NC_RIGID_FT1200:
/* 100 Watts */
*power = mwpower / 100000.0;
rig_debug(RIG_DEBUG_TRACE, "case FT1200 - rig_id = %d, *power = %f\n", rig_id,
*power);
break;
default:
/* 100 Watts */
*power = mwpower / 100000.0;
rig_debug(RIG_DEBUG_TRACE, "default - rig_id = %d, *power = %f\n", rig_id,
*power);
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_set_powerstat(RIG *rig, powerstat_t status)
{
struct rig_state *state = &rig->state;
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char ps;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "PS"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
switch (status)
{
case RIG_POWER_ON:
ps = '1';
// when powering on need a dummy byte to wake it up
// then sleep from 1 to 2 seconds so we'll do 1.5 secs
write_block(&state->rigport, "\n", 1);
hl_usleep(1500000);
2019-11-30 16:19:08 +00:00
break;
case RIG_POWER_OFF:
case RIG_POWER_STANDBY:
ps = '0';
break;
default:
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PS%c%c", ps, cat_term);
2019-11-30 16:19:08 +00:00
err = write_block(&state->rigport, priv->cmd_str, strlen(priv->cmd_str));
return err;
}
/*
* This functions returns an error if the rig is off, dah
*/
2019-11-30 16:19:08 +00:00
int newcat_get_powerstat(RIG *rig, powerstat_t *status)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char ps;
char command[] = "PS";
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
*status = RIG_POWER_OFF;
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term);
2019-11-30 16:19:08 +00:00
/* Get Power status */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
ps = priv->ret_data[2];
2019-11-30 16:19:08 +00:00
switch (ps)
{
case '1':
*status = RIG_POWER_ON;
break;
case '0':
*status = RIG_POWER_OFF;
break;
default:
return -RIG_ENAVAIL;
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_reset(RIG *rig, reset_t reset)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char which_ant;
char command[] = "AN";
char main_sub_vfo = '0';
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
/* Main or SUB vfo */
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
2019-11-30 16:19:08 +00:00
{
main_sub_vfo = RIG_VFO_B == vfo ? '1' : '0';
}
2019-11-30 16:19:08 +00:00
switch (ant)
{
case RIG_ANT_1:
which_ant = '1';
break;
case RIG_ANT_2:
which_ant = '2';
break;
case RIG_ANT_3:
if (newcat_is_rig(rig, RIG_MODEL_FT950)) /* FT2000 also */
{
return -RIG_EINVAL;
}
if (newcat_is_rig(rig, RIG_MODEL_FT1200)) /* FT2000 also */
{
return -RIG_EINVAL;
}
which_ant = '3';
break;
case RIG_ANT_4:
if (newcat_is_rig(rig, RIG_MODEL_FT950))
{
return -RIG_EINVAL;
}
if (newcat_is_rig(rig, RIG_MODEL_FT1200))
{
return -RIG_EINVAL;
}
which_ant = '4';
break;
case RIG_ANT_5:
if (newcat_is_rig(rig, RIG_MODEL_FT950))
{
return -RIG_EINVAL;
}
if (newcat_is_rig(rig, RIG_MODEL_FT1200))
{
return -RIG_EINVAL;
}
/* RX only, on FT-2000/FT-5000/FT-9000 */
which_ant = '5';
break;
default:
return -RIG_EINVAL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c%c", command,
main_sub_vfo, which_ant, cat_term);
return newcat_set_cmd(rig);
}
2020-02-23 17:26:09 +00:00
int newcat_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option,
ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char c;
char command[] = "AN";
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
/* Set Main or SUB vfo */
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
2019-11-30 16:19:08 +00:00
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
2019-11-30 16:19:08 +00:00
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, main_sub_vfo,
cat_term);
/* Get ANT */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
c = priv->ret_data[3];
2019-11-30 16:19:08 +00:00
switch (c)
{
case '1':
*ant_curr = RIG_ANT_1;
2019-11-30 16:19:08 +00:00
break;
case '2' :
*ant_curr = RIG_ANT_2;
2019-11-30 16:19:08 +00:00
break;
case '3' :
*ant_curr = RIG_ANT_3;
2019-11-30 16:19:08 +00:00
break;
case '4' :
*ant_curr = RIG_ANT_4;
2019-11-30 16:19:08 +00:00
break;
case '5' :
*ant_curr = RIG_ANT_5;
2019-11-30 16:19:08 +00:00
break;
default:
*ant_curr = RIG_ANT_UNKNOWN;
2019-11-30 16:19:08 +00:00
return -RIG_EPROTO;
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
{
struct rig_state *state = &rig->state;
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
int i;
int scale;
int fpf;
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
/* Set Main or SUB vfo */
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
/* Start with both but mostly FT9000 */
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
2019-11-30 16:19:08 +00:00
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
switch (level)
{
case RIG_LEVEL_RFPOWER:
if (!newcat_valid_command(rig, "PC"))
{
return -RIG_ENAVAIL;
}
scale = (newcat_is_rig(rig, RIG_MODEL_FT450)) &&
(newcat_get_rigid(rig) == NC_RIGID_FT450D) ? 100. : 255.;
scale = newcat_is_rig(rig, RIG_MODEL_FT891) ? 100. : scale ;
scale = newcat_is_rig(rig, RIG_MODEL_FT950) ? 100. : scale ;
scale = newcat_is_rig(rig, RIG_MODEL_FT1200) ? 100. : scale ;
fpf = newcat_scale_float(scale, val.f);
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PC%03d%c", fpf, cat_term);
break;
case RIG_LEVEL_AF:
if (!newcat_valid_command(rig, "AG"))
{
return -RIG_ENAVAIL;
}
fpf = newcat_scale_float(255, val.f);
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AG%c%03d%c", main_sub_vfo, fpf,
cat_term);
break;
case RIG_LEVEL_AGC:
if (!newcat_valid_command(rig, "GT"))
{
return -RIG_ENAVAIL;
}
switch (val.i)
{
case RIG_AGC_OFF: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT00;");
break;
2019-11-30 16:19:08 +00:00
case RIG_AGC_FAST: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT01;");
break;
2019-11-30 16:19:08 +00:00
case RIG_AGC_MEDIUM: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT02;");
break;
2019-11-30 16:19:08 +00:00
case RIG_AGC_SLOW: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT03;");
break;
2019-11-30 16:19:08 +00:00
case RIG_AGC_AUTO: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT04;");
break;
2019-11-30 16:19:08 +00:00
default: return -RIG_EINVAL;
}
priv->cmd_str[2] = main_sub_vfo;
break;
case RIG_LEVEL_IF:
if (!newcat_valid_command(rig, "IS"))
{
return -RIG_ENAVAIL;
}
if (abs(val.i) > rig->caps->max_ifshift)
{
if (val.i > 0)
{
val.i = rig->caps->max_ifshift;
}
2019-11-30 16:19:08 +00:00
else
{
val.i = rig->caps->max_ifshift * -1;
}
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "IS0%+.4d%c", val.i,
cat_term); /* problem with %+04d */
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
}
break;
case RIG_LEVEL_CWPITCH:
if (!newcat_valid_command(rig, "KP"))
{
return -RIG_ENAVAIL;
}
if (val.i < 300)
{
i = 300;
}
else if (val.i > 1050)
{
i = 1050;
}
else
{
i = val.i;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "KP%02d%c",
2 * ((i + 50 - 300) / 100), cat_term);
break;
case RIG_LEVEL_KEYSPD:
if (!newcat_valid_command(rig, "KS"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "KS%03d%c", val.i, cat_term);
break;
case RIG_LEVEL_MICGAIN:
if (!newcat_valid_command(rig, "MG"))
{
return -RIG_ENAVAIL;
}
if (newcat_is_rig(rig, RIG_MODEL_FT1200))
{
fpf = newcat_scale_float(100, val.f);
}
else
{
fpf = newcat_scale_float(255, val.f);
2019-11-30 16:19:08 +00:00
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MG%03d%c", fpf, cat_term);
break;
case RIG_LEVEL_METER:
if (!newcat_valid_command(rig, "MS"))
{
return -RIG_ENAVAIL;
}
switch (val.i)
{
case RIG_METER_ALC: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MS1;");
break;
2019-11-30 16:19:08 +00:00
case RIG_METER_PO:
if (newcat_is_rig(rig, RIG_MODEL_FT950))
{
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
else
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MS2;");
}
2019-11-30 16:19:08 +00:00
break;
2019-11-30 16:19:08 +00:00
case RIG_METER_SWR: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MS3;");
break;
2019-11-30 16:19:08 +00:00
case RIG_METER_COMP: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MS0;");
break;
2019-11-30 16:19:08 +00:00
case RIG_METER_IC: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MS4;");
break;
2019-11-30 16:19:08 +00:00
case RIG_METER_VDD: snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MS5;");
break;
2019-11-30 16:19:08 +00:00
default: return -RIG_EINVAL;
}
break;
case RIG_LEVEL_PREAMP:
if (!newcat_valid_command(rig, "PA"))
{
return -RIG_ENAVAIL;
}
if (val.i == 0)
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PA00%c", cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
2019-11-30 16:19:08 +00:00
}
break;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
priv->cmd_str[0] = '\0';
2019-11-30 16:19:08 +00:00
for (i = 0; state->preamp[i] != RIG_DBLST_END; i++)
if (state->preamp[i] == val.i)
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PA0%d%c", i + 1, cat_term);
break;
}
2019-11-30 16:19:08 +00:00
if (strlen(priv->cmd_str) != 0)
{
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
}
2019-11-30 16:19:08 +00:00
break;
}
return -RIG_EINVAL;
2019-11-30 16:19:08 +00:00
case RIG_LEVEL_ATT:
if (!newcat_valid_command(rig, "RA"))
{
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
if (val.i == 0)
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RA00%c", cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
2019-11-30 16:19:08 +00:00
{
priv->cmd_str[2] = main_sub_vfo;
2019-11-30 16:19:08 +00:00
}
break;
2019-11-30 16:19:08 +00:00
}
priv->cmd_str[0] = '\0';
for (i = 0; state->attenuator[i] != RIG_DBLST_END; i++)
if (state->attenuator[i] == val.i)
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RA0%d%c", i + 1, cat_term);
break; /* for loop */
}
if (strlen(priv->cmd_str) != 0)
{
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
2019-11-30 16:19:08 +00:00
{
priv->cmd_str[2] = main_sub_vfo;
2019-11-30 16:19:08 +00:00
}
break;
2019-11-30 16:19:08 +00:00
}
return -RIG_EINVAL;
case RIG_LEVEL_RF:
if (!newcat_valid_command(rig, "RG"))
{
return -RIG_ENAVAIL;
}
fpf = newcat_scale_float(255, val.f);
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RG%c%03d%c", main_sub_vfo, fpf,
cat_term);
break;
case RIG_LEVEL_NR:
if (!newcat_valid_command(rig, "RL"))
{
return -RIG_ENAVAIL;
}
if (newcat_is_rig(rig, RIG_MODEL_FT450))
{
fpf = newcat_scale_float(11, val.f);
if (fpf < 1)
{
fpf = 1;
}
if (fpf > 11)
{
fpf = 11;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RL0%02d%c", fpf, cat_term);
}
else
{
fpf = newcat_scale_float(15, val.f);
if (fpf < 1)
{
fpf = 1;
}
if (fpf > 15)
{
fpf = 15;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RL0%02d%c", fpf, cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
2019-11-30 16:19:08 +00:00
{
priv->cmd_str[2] = main_sub_vfo;
2019-11-30 16:19:08 +00:00
}
}
2019-11-30 16:19:08 +00:00
break;
2019-11-30 16:19:08 +00:00
case RIG_LEVEL_COMP:
if (!newcat_valid_command(rig, "PL"))
{
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
scale = (newcat_is_rig(rig, RIG_MODEL_FT950)) ? 100 : 255;
scale = (newcat_is_rig(rig, RIG_MODEL_FT1200)) ? 100 : scale ;
fpf = newcat_scale_float(scale, val.f);
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PL%03d%c", fpf, cat_term);
break;
case RIG_LEVEL_BKINDL:
/* Standard: word "PARIS" == 50 Unit Intervals, UIs */
/* 1 dot == 2 UIs */
/* tenth_dots-per-second -to- milliseconds */
if (!newcat_valid_command(rig, "SD"))
{
return -RIG_ENAVAIL;
}
if (val.i < 1)
{
val.i = 1;
}
val.i = 5000 / val.i;
if (newcat_is_rig(rig, RIG_MODEL_FT950) || newcat_is_rig(rig, RIG_MODEL_FT450)
|| newcat_is_rig(rig, RIG_MODEL_FT1200))
{
if (val.i < 30)
{
val.i = 30;
}
2019-11-30 16:19:08 +00:00
if (val.i > 3000)
{
val.i = 3000;
}
2019-11-30 16:19:08 +00:00
}
else if (newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
{
if (val.i < 1)
{
val.i = 1;
}
if (val.i > 5000)
{
val.i = 5000;
}
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", val.i, cat_term);
break;
case RIG_LEVEL_SQL:
if (!newcat_valid_command(rig, "SQ"))
{
return -RIG_ENAVAIL;
}
fpf = newcat_scale_float(255, val.f);
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SQ%c%03d%c", main_sub_vfo, fpf,
cat_term);
break;
case RIG_LEVEL_VOXDELAY:
2019-11-30 16:19:08 +00:00
if (!newcat_valid_command(rig, "VD"))
{
return -RIG_ENAVAIL;
}
/* VOX delay, arg int (tenth of seconds), 100ms UI */
val.i = val.i * 100;
if (newcat_is_rig(rig, RIG_MODEL_FT950) || newcat_is_rig(rig, RIG_MODEL_FT450)
|| newcat_is_rig(rig, RIG_MODEL_FT1200))
{
if (val.i < 100) /* min is 30ms but spec is 100ms Unit Intervals */
{
val.i = 30;
}
if (val.i > 3000)
{
val.i = 3000;
}
}
else if (newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
{
if (val.i < 0)
{
val.i = 0;
}
if (val.i > 5000)
{
val.i = 5000;
}
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VD%04d%c", val.i, cat_term);
break;
case RIG_LEVEL_VOXGAIN:
if (!newcat_valid_command(rig, "VG"))
{
return -RIG_ENAVAIL;
}
scale = (newcat_is_rig(rig, RIG_MODEL_FT950)) ? 100 : 255;
scale = (newcat_is_rig(rig, RIG_MODEL_FT1200)) ? 100 : scale;
fpf = newcat_scale_float(scale, val.f);
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VG%03d%c", fpf, cat_term);
break;
case RIG_LEVEL_ANTIVOX:
if (newcat_is_rig(rig, RIG_MODEL_FT950))
{
fpf = newcat_scale_float(100, val.f);
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%03d%c", fpf, cat_term);
}
else if (newcat_is_rig(rig, RIG_MODEL_FT1200))
{
fpf = newcat_scale_float(100, val.f);
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX183%03d%c", fpf, cat_term);
}
else
{
return -RIG_EINVAL;
2019-11-30 16:19:08 +00:00
}
break;
case RIG_LEVEL_NOTCHF:
if (!newcat_valid_command(rig, "BP"))
{
return -RIG_ENAVAIL;
}
val.i = val.i / 10;
if (val.i < 1) /* fix lower bounds limit */
{
val.i = 1;
}
if (newcat_is_rig(rig, RIG_MODEL_FT950))
{
if (val.i > 300)
{
val.i = 300;
}
}
else
{
if (val.i > 400)
{
val.i = 400;
}
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP01%03d%c", val.i, cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000)) /* The old CAT Man. shows VFO */
{
priv->cmd_str[2] = main_sub_vfo;
}
break;
default:
return -RIG_EINVAL;
}
2019-11-30 16:19:08 +00:00
return newcat_set_cmd(rig);
}
2019-11-30 16:19:08 +00:00
int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
{
2019-11-30 16:19:08 +00:00
struct rig_state *state = &rig->state;
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
2019-11-30 16:19:08 +00:00
int ret_data_len;
char *retlvl;
float scale;
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
/* Set Main or SUB vfo */
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
2019-11-30 16:19:08 +00:00
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
switch (level)
{
case RIG_LEVEL_RFPOWER:
if (!newcat_valid_command(rig, "PC"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PC%c", cat_term);
break;
case RIG_LEVEL_PREAMP:
if (!newcat_valid_command(rig, "PA"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PA0%c", cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
break;
2019-11-30 16:19:08 +00:00
case RIG_LEVEL_AF:
if (!newcat_valid_command(rig, "AG"))
{
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AG%c%c", main_sub_vfo,
cat_term);
break;
2019-11-30 16:19:08 +00:00
case RIG_LEVEL_AGC:
if (!newcat_valid_command(rig, "GT"))
{
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "GT%c%c", main_sub_vfo,
cat_term);
break;
2019-11-30 16:19:08 +00:00
case RIG_LEVEL_IF:
if (!newcat_valid_command(rig, "IS"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "IS0%c", cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
2019-11-30 16:19:08 +00:00
}
break;
case RIG_LEVEL_CWPITCH:
if (!newcat_valid_command(rig, "KP"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "KP%c", cat_term);
break;
case RIG_LEVEL_KEYSPD:
if (!newcat_valid_command(rig, "KS"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "KS%c", cat_term);
break;
case RIG_LEVEL_MICGAIN:
if (!newcat_valid_command(rig, "MG"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MG%c", cat_term);
break;
case RIG_LEVEL_METER:
if (!newcat_valid_command(rig, "MS"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MS%c", cat_term);
break;
case RIG_LEVEL_ATT:
if (!newcat_valid_command(rig, "RA"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RA0%c", cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
2019-11-30 16:19:08 +00:00
}
break;
case RIG_LEVEL_RF:
if (!newcat_valid_command(rig, "RG"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RG%c%c", main_sub_vfo,
cat_term);
break;
case RIG_LEVEL_COMP:
if (!newcat_valid_command(rig, "PL"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PL%c", cat_term);
break;
case RIG_LEVEL_NR:
if (!newcat_valid_command(rig, "RL"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RL0%c", cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
2019-11-30 16:19:08 +00:00
}
break;
case RIG_LEVEL_BKINDL:
if (!newcat_valid_command(rig, "SD"))
{
return -RIG_ENAVAIL;
}
/* should be tenth of dots */
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SD%c", cat_term);
break;
case RIG_LEVEL_SQL:
if (!newcat_valid_command(rig, "SQ"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SQ%c%c", main_sub_vfo,
cat_term);
break;
case RIG_LEVEL_VOXDELAY:
2019-11-30 16:19:08 +00:00
/* VOX delay, arg int (tenth of seconds) */
if (!newcat_valid_command(rig, "VD"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VD%c", cat_term);
break;
case RIG_LEVEL_VOXGAIN:
if (!newcat_valid_command(rig, "VG"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VG%c", cat_term);
break;
/*
* Read only levels
*/
case RIG_LEVEL_STRENGTH:
case RIG_LEVEL_RAWSTR:
if (!newcat_valid_command(rig, "SM"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SM%c%c", main_sub_vfo,
cat_term);
break;
case RIG_LEVEL_SWR:
if (!newcat_valid_command(rig, "RM"))
{
return -RIG_ENAVAIL;
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RM09%c", cat_term);
}
else
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RM6%c", cat_term);
}
break;
case RIG_LEVEL_ALC:
if (!newcat_valid_command(rig, "RM"))
{
return -RIG_ENAVAIL;
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RM07%c", cat_term);
}
else
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RM4%c", cat_term);
}
break;
case RIG_LEVEL_ANTIVOX:
if (newcat_is_rig(rig, RIG_MODEL_FT950))
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX117%c", cat_term);
}
else if (newcat_is_rig(rig, RIG_MODEL_FT1200))
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "EX183%c", cat_term);
}
else
{
return -RIG_EINVAL;
2019-11-30 16:19:08 +00:00
}
break;
case RIG_LEVEL_NOTCHF:
if (!newcat_valid_command(rig, "BP"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP01%c", cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
}
break;
default:
return -RIG_EINVAL;
}
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
ret_data_len = strlen(priv->ret_data);
/* skip command */
2019-11-30 16:19:08 +00:00
retlvl = priv->ret_data + strlen(priv->cmd_str) - 1;
/* chop term */
2019-11-30 16:19:08 +00:00
priv->ret_data[ret_data_len - 1] = '\0';
2019-11-30 16:19:08 +00:00
switch (level)
{
case RIG_LEVEL_RFPOWER:
scale = (newcat_is_rig(rig, RIG_MODEL_FT450)) &&
(newcat_get_rigid(rig) == NC_RIGID_FT450D) ? 100. : 255.;
scale = newcat_is_rig(rig, RIG_MODEL_FT891) ? 100. : scale ;
scale = newcat_is_rig(rig, RIG_MODEL_FT950) ? 100. : scale ;
scale = newcat_is_rig(rig, RIG_MODEL_FT1200) ? 100. : scale ;
val->f = (float)atoi(retlvl) / scale;
break;
case RIG_LEVEL_VOXGAIN:
case RIG_LEVEL_COMP:
case RIG_LEVEL_ANTIVOX:
scale = (newcat_is_rig(rig, RIG_MODEL_FT950)) ? 100. : 255.;
scale = (newcat_is_rig(rig, RIG_MODEL_FT1200)) ? 100. : scale ;
val->f = (float)atoi(retlvl) / scale;
break;
case RIG_LEVEL_AF:
case RIG_LEVEL_MICGAIN:
case RIG_LEVEL_RF:
case RIG_LEVEL_SQL:
case RIG_LEVEL_SWR:
case RIG_LEVEL_ALC:
val->f = (float)atoi(retlvl) / 255.;
break;
case RIG_LEVEL_BKINDL:
val->i = atoi(retlvl); /* milliseconds */
if (val->i < 1)
{
val->i = 1;
}
val->i = 5000 / val->i; /* ms -to- tenth_dots-per-second */
if (val->i < 1)
{
val->i = 1;
}
break;
case RIG_LEVEL_STRENGTH: // Yaesu's return straight s-meter answers
2020-02-23 17:26:09 +00:00
2020-02-09 04:54:36 +00:00
if (newcat_is_rig(rig, RIG_MODEL_FT991))
{
// value of 0.448 determined by data from W6HN
// seems to be pretty linear
2020-02-09 04:59:12 +00:00
// SMeter, rig answer, %fullscale
// S0 SM0000 0
// S2 SM0026 10
// S4 SM0051 20
// S6 SM0081 30
// S7.5 SM0105 40
// S9 SM0130 50
// +12db SM0157 60
// +25db SM0186 70
// +35db SM0203 80
// +50db SM0237 90
2020-02-10 21:23:43 +00:00
// +60db SM0255 100
2020-02-23 17:26:09 +00:00
// 114dB range over 0-255 referenced to S0 of -54dB
val->i = atoi(retlvl) * (114.0 / 255.0) - 54;
2020-02-09 04:54:36 +00:00
}
else // some Yaesu's return straight s-meter answers
2020-02-23 17:26:09 +00:00
{
2020-02-09 04:54:36 +00:00
// Return dbS9 -- does >S9 mean 10dB increments? If not, add to rig driver
if (val->i > 0) { val->i = (atoi(retlvl) - 9) * 10; }
else { val->i = (atoi(retlvl) - 9) * 6; } // Return dbS9 does >S9 mean 10dB increments?
}
2019-11-30 16:19:08 +00:00
break;
case RIG_LEVEL_RAWSTR:
case RIG_LEVEL_KEYSPD:
case RIG_LEVEL_IF:
val->i = atoi(retlvl);
break;
case RIG_LEVEL_NR:
/* ratio 0 - 1.0 */
if (newcat_is_rig(rig, RIG_MODEL_FT450))
{
val->f = (float)(atoi(retlvl) / 11.);
}
else
{
val->f = (float)(atoi(retlvl) / 15.);
}
break;
case RIG_LEVEL_VOXDELAY:
2019-11-30 16:19:08 +00:00
/* VOX delay, arg int (tenth of seconds), 100ms intervals */
val->i = atoi(retlvl) / 100;
break;
case RIG_LEVEL_PREAMP:
if (retlvl[0] < '0' || retlvl[0] > '9')
{
return -RIG_EPROTO;
}
val->i = (retlvl[0] == '0') ? 0 : state->preamp[retlvl[0] - '1'];
break;
case RIG_LEVEL_ATT:
if (retlvl[0] < '0' || retlvl[0] > '9')
{
return -RIG_EPROTO;
}
val->i = (retlvl[0] == '0') ? 0 : state->attenuator[retlvl[0] - '1'];
break;
case RIG_LEVEL_AGC:
switch (retlvl[0])
{
case '0': val->i = RIG_AGC_OFF; break;
case '1': val->i = RIG_AGC_FAST; break;
case '2': val->i = RIG_AGC_MEDIUM; break;
case '3': val->i = RIG_AGC_SLOW; break;
case '4':
case '5':
case '6':
val->i = RIG_AGC_AUTO; break;
default: return -RIG_EPROTO;
}
break;
case RIG_LEVEL_CWPITCH:
val->i = (atoi(retlvl) / 2) * 100 + 300;
break;
case RIG_LEVEL_METER:
switch (retlvl[0])
{
case '0': val->i = RIG_METER_COMP; break;
case '1': val->i = RIG_METER_ALC; break;
case '2': val->i = RIG_METER_PO; break;
case '3': val->i = RIG_METER_SWR; break;
case '4': val->i = RIG_METER_IC; break; /* ID CURRENT */
case '5': val->i = RIG_METER_VDD; break; /* Final Amp Voltage */
default: return -RIG_EPROTO;
}
break;
case RIG_LEVEL_NOTCHF:
val->i = atoi(retlvl) * 10;
break;
default:
return -RIG_EINVAL;
}
return RIG_OK;
}
int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
/* Set Main or SUB vfo */
err = newcat_set_vfo_from_alias(rig, &vfo);
if (err < 0)
{
return err;
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
}
switch (func)
{
case RIG_FUNC_ANF:
if (!newcat_valid_command(rig, "BC"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BC0%d%c", status ? 1 : 0,
cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
}
break;
case RIG_FUNC_MN:
if (!newcat_valid_command(rig, "BP"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP00%03d%c", status ? 1 : 0,
cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
}
break;
case RIG_FUNC_FBKIN:
if (!newcat_valid_command(rig, "BI"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BI%d%c", status ? 1 : 0,
cat_term);
break;
case RIG_FUNC_TONE:
if (!newcat_valid_command(rig, "CT"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CT0%d%c", status ? 2 : 0,
cat_term);
priv->cmd_str[2] = main_sub_vfo;
break;
case RIG_FUNC_TSQL:
if (!newcat_valid_command(rig, "CT"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CT0%d%c", status ? 1 : 0,
cat_term);
priv->cmd_str[2] = main_sub_vfo;
break;
case RIG_FUNC_LOCK:
if (!newcat_valid_command(rig, "LK"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "LK%d%c", status ? 1 : 0,
cat_term);
break;
case RIG_FUNC_MON:
if (!newcat_valid_command(rig, "ML"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML0%03d%c", status ? 1 : 0,
cat_term);
break;
case RIG_FUNC_NB:
if (!newcat_valid_command(rig, "NB"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "NB0%d%c", status ? 1 : 0,
cat_term);
priv->cmd_str[2] = main_sub_vfo;
break;
case RIG_FUNC_NR:
if (!newcat_valid_command(rig, "NR"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "NR0%d%c", status ? 1 : 0,
cat_term);
priv->cmd_str[2] = main_sub_vfo;
break;
case RIG_FUNC_COMP:
if (!newcat_valid_command(rig, "PR"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR%d%c", status ? 1 : 0,
cat_term);
break;
case RIG_FUNC_VOX:
if (!newcat_valid_command(rig, "VX"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VX%d%c", status ? 1 : 0,
cat_term);
break;
case RIG_FUNC_TUNER:
if (!newcat_valid_command(rig, "AC"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AC00%d%c", status ? 1 : 0,
cat_term);
break;
default:
return -RIG_EINVAL;
}
return newcat_set_cmd(rig);
}
int newcat_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
int ret_data_len;
char *retfunc;
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
switch (func)
{
case RIG_FUNC_ANF:
if (!newcat_valid_command(rig, "BC"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BC0%c", cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
}
break;
case RIG_FUNC_MN:
if (!newcat_valid_command(rig, "BP"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BP00%c", cat_term);
if (newcat_is_rig(rig, RIG_MODEL_FT9000))
{
priv->cmd_str[2] = main_sub_vfo;
}
break;
case RIG_FUNC_FBKIN:
if (!newcat_valid_command(rig, "BI"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BI%c", cat_term);
break;
case RIG_FUNC_TONE:
if (!newcat_valid_command(rig, "CT"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CT0%c", cat_term);
priv->cmd_str[2] = main_sub_vfo;
break;
case RIG_FUNC_TSQL:
if (!newcat_valid_command(rig, "CT"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "CT0%c", cat_term);
priv->cmd_str[2] = main_sub_vfo;
break;
case RIG_FUNC_LOCK:
if (!newcat_valid_command(rig, "LK"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "LK%c", cat_term);
break;
case RIG_FUNC_MON:
if (!newcat_valid_command(rig, "ML"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ML0%c", cat_term);
break;
case RIG_FUNC_NB:
if (!newcat_valid_command(rig, "NB"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "NB0%c", cat_term);
priv->cmd_str[2] = main_sub_vfo;
break;
case RIG_FUNC_NR:
if (!newcat_valid_command(rig, "NR"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "NR0%c", cat_term);
priv->cmd_str[2] = main_sub_vfo;
break;
case RIG_FUNC_COMP:
if (!newcat_valid_command(rig, "PR"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "PR%c", cat_term);
break;
case RIG_FUNC_VOX:
if (!newcat_valid_command(rig, "VX"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VX%c", cat_term);
break;
case RIG_FUNC_TUNER:
if (!newcat_valid_command(rig, "AC"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AC%c", cat_term);
break;
default:
return -RIG_EINVAL;
}
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
}
ret_data_len = strlen(priv->ret_data);
/* skip command */
retfunc = priv->ret_data + strlen(priv->cmd_str) - 1;
/* chop term */
priv->ret_data[ret_data_len - 1] = '\0';
switch (func)
{
case RIG_FUNC_MN:
*status = (retfunc[2] == '0') ? 0 : 1;
break;
case RIG_FUNC_ANF:
case RIG_FUNC_FBKIN:
case RIG_FUNC_LOCK:
case RIG_FUNC_MON:
case RIG_FUNC_NB:
case RIG_FUNC_NR:
case RIG_FUNC_COMP:
case RIG_FUNC_VOX:
*status = (retfunc[0] == '0') ? 0 : 1;
break;
case RIG_FUNC_TONE:
*status = (retfunc[0] == '2') ? 1 : 0;
break;
case RIG_FUNC_TSQL:
*status = (retfunc[0] == '1') ? 1 : 0;
break;
case RIG_FUNC_TUNER:
*status = (retfunc[2] == '1') ? 1 : 0;
break;
default:
return -RIG_EINVAL;
}
return RIG_OK;
}
int newcat_set_parm(RIG *rig, setting_t parm, value_t val)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_get_parm(RIG *rig, setting_t parm, value_t *val)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_set_ext_parm(RIG *rig, token_t token, value_t val)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_get_ext_parm(RIG *rig, token_t token, value_t *val)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_send_dtmf(RIG *rig, vfo_t vfo, const char *digits)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_send_morse(RIG *rig, vfo_t vfo, const char *msg)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_set_bank(RIG *rig, vfo_t vfo, int bank)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_set_mem(RIG *rig, vfo_t vfo, int ch)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err, i;
ncboolean restore_vfo;
chan_t *chan_list;
channel_t valid_chan;
channel_cap_t *mem_caps = NULL;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "MC"))
{
return -RIG_ENAVAIL;
}
chan_list = rig->caps->chan_list;
for (i = 0; i < CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++)
{
if (ch >= chan_list[i].startc &&
ch <= chan_list[i].endc)
{
mem_caps = &chan_list[i].mem_caps;
break;
}
}
/* Test for valid usable channel, skip if empty */
memset(&valid_chan, 0, sizeof(channel_t));
valid_chan.channel_num = ch;
err = newcat_get_channel(rig, &valid_chan);
2019-12-24 16:00:45 +00:00
if (err < 0)
{
return err;
}
2019-11-30 16:19:08 +00:00
if (valid_chan.freq <= 1.0)
{
mem_caps = NULL;
}
rig_debug(RIG_DEBUG_TRACE, "%s: valChan Freq = %f\n", __func__,
valid_chan.freq);
/* Out of Range, or empty */
if (!mem_caps)
{
return -RIG_ENAVAIL;
}
/* set to usable vfo if needed */
err = newcat_set_vfo_from_alias(rig, &vfo);
if (err < 0)
{
return err;
}
/* Restore to VFO mode or leave in Memory Mode */
switch (vfo)
{
case RIG_VFO_A:
/* Jump back from memory channel */
restore_vfo = TRUE;
break;
case RIG_VFO_MEM:
/* Jump from channel to channel in memmory mode */
restore_vfo = FALSE;
break;
case RIG_VFO_B:
default:
/* Only works with VFO A */
return -RIG_ENTARGET;
}
/* Set Memory Channel Number ************** */
2020-03-20 12:51:32 +00:00
rig_debug(RIG_DEBUG_TRACE, "channel_num = %d, vfo = %s\n", ch, rig_strvfo(vfo));
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MC%03d%c", ch, cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
err = newcat_set_cmd(rig);
if (err != RIG_OK)
{
return err;
}
/* Restore VFO even if setting to blank memory channel */
if (restore_vfo)
{
err = newcat_vfomem_toggle(rig);
if (err != RIG_OK)
{
return err;
}
}
return RIG_OK;
}
int newcat_get_mem(RIG *rig, vfo_t vfo, int *ch)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "MC"))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MC%c", cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
/* Get Memory Channel Number */
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
}
*ch = atoi(priv->ret_data + 2);
return RIG_OK;
}
int newcat_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
/* Set Main or SUB vfo */
err = newcat_set_vfo_from_alias(rig, &vfo);
if (err < 0)
{
return err;
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000))
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
}
switch (op)
{
case RIG_OP_TUNE:
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AC002%c", cat_term);
break;
case RIG_OP_CPY:
if (newcat_is_rig(rig, RIG_MODEL_FT450))
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "VV%c", cat_term);
}
else
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AB%c", cat_term);
}
break;
case RIG_OP_XCHG:
case RIG_OP_TOGGLE:
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "SV%c", cat_term);
break;
case RIG_OP_UP:
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "UP%c", cat_term);
break;
case RIG_OP_DOWN:
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "DN%c", cat_term);
break;
case RIG_OP_BAND_UP:
if (main_sub_vfo == 1)
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BU1%c", cat_term);
}
else
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BU0%c", cat_term);
}
break;
case RIG_OP_BAND_DOWN:
if (main_sub_vfo == 1)
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BD1%c", cat_term);
}
else
{
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "BD0%c", cat_term);
}
break;
case RIG_OP_FROM_VFO:
/* VFOA ! */
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AM%c", cat_term);
break;
case RIG_OP_TO_VFO:
/* VFOA ! */
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MA%c", cat_term);
break;
default:
return -RIG_EINVAL;
}
return newcat_set_cmd(rig);
}
int newcat_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_set_trn(RIG *rig, int trn)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
char c;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "AI"))
{
return -RIG_ENAVAIL;
}
if (trn == RIG_TRN_OFF)
{
c = '0';
}
else
{
c = '1';
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "AI%c%c", c, cat_term);
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str);
return newcat_set_cmd(rig);
}
int newcat_get_trn(RIG *rig, int *trn)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char c;
char command[] = "AI";
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, command))
{
return -RIG_ENAVAIL;
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term);
/* Get Auto Information */
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
}
c = priv->ret_data[2];
if (c == '0')
{
*trn = RIG_TRN_OFF;
}
else
{
*trn = RIG_TRN_RIG;
}
return RIG_OK;
}
int newcat_decode_event(RIG *rig)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
return -RIG_ENAVAIL;
}
int newcat_set_channel(RIG *rig, const channel_t *chan)
{
struct rig_state *state = &rig->state;
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err, i;
int rxit;
char c_rit, c_xit, c_mode, c_vfo, c_tone, c_rptr_shift;
tone_t tone;
ncboolean restore_vfo;
chan_t *chan_list;
channel_cap_t *mem_caps = NULL;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "MW"))
{
return -RIG_ENAVAIL;
}
chan_list = rig->caps->chan_list;
for (i = 0; i < CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++)
{
if (chan->channel_num >= chan_list[i].startc &&
chan->channel_num <= chan_list[i].endc &&
// writable memory types... NOT 60-METERS or READ-ONLY channels
(chan_list[i].type == RIG_MTYPE_MEM ||
chan_list[i].type == RIG_MTYPE_EDGE))
{
mem_caps = &chan_list[i].mem_caps;
break;
}
}
/* Out of Range */
if (!mem_caps)
{
return -RIG_ENAVAIL;
}
/* Set Restore to VFO or leave in memory mode */
switch (state->current_vfo)
{
case RIG_VFO_A:
/* Jump back from memory channel */
restore_vfo = TRUE;
break;
case RIG_VFO_MEM:
/* Jump from channel to channel in memmory mode */
restore_vfo = FALSE;
break;
case RIG_VFO_B:
default:
/* Only works with VFO A */
return -RIG_ENTARGET;
}
/* Write Memory Channel ************************* */
/* Clarifier TX, RX */
if (chan->rit)
{
rxit = chan->rit;
c_rit = '1';
c_xit = '0';
}
else if (chan->xit)
{
rxit = chan->xit;
c_rit = '0';
c_xit = '1';
}
else
{
rxit = 0;
c_rit = '0';
c_xit = '0';
}
/* MODE */
switch (chan->mode)
{
case RIG_MODE_LSB: c_mode = '1'; break;
case RIG_MODE_USB: c_mode = '2'; break;
case RIG_MODE_CW: c_mode = '3'; break;
case RIG_MODE_FM: c_mode = '4'; break;
case RIG_MODE_AM: c_mode = '5'; break;
case RIG_MODE_RTTY: c_mode = '6'; break;
case RIG_MODE_CWR: c_mode = '7'; break;
case RIG_MODE_PKTLSB: c_mode = '8'; break;
case RIG_MODE_RTTYR: c_mode = '9'; break;
case RIG_MODE_PKTFM: c_mode = 'A'; break;
2020-01-15 14:15:29 +00:00
case RIG_MODE_FMN: c_mode = 'B'; break;
2019-11-30 16:19:08 +00:00
case RIG_MODE_PKTUSB: c_mode = 'C'; break;
2020-01-15 14:15:29 +00:00
case RIG_MODE_AMN: c_mode = 'D'; break;
case RIG_MODE_C4FM: c_mode = 'E'; break;
2019-11-30 16:19:08 +00:00
default: c_mode = '1'; break;
}
/* VFO Fixed */
c_vfo = '0';
/* CTCSS Tone / Sql */
if (chan->ctcss_tone)
{
c_tone = '2';
tone = chan->ctcss_tone;
}
else if (chan->ctcss_sql)
{
c_tone = '1';
tone = chan->ctcss_sql;
}
else
{
c_tone = '0';
tone = 0;
}
for (i = 0; rig->caps->ctcss_list[i] != 0; i++)
if (tone == rig->caps->ctcss_list[i])
{
tone = i;
if (tone > 49)
{
tone = 0;
}
break;
}
/* Repeater Shift */
switch (chan->rptr_shift)
{
case RIG_RPT_SHIFT_NONE: c_rptr_shift = '0'; break;
case RIG_RPT_SHIFT_PLUS: c_rptr_shift = '1'; break;
case RIG_RPT_SHIFT_MINUS: c_rptr_shift = '2'; break;
default: c_rptr_shift = '0';
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str),
2020-03-20 12:51:32 +00:00
"MW%03d%08d%+.4d%c%c%c%c%c%02u%c%c",
2019-11-30 16:19:08 +00:00
chan->channel_num, (int)chan->freq, rxit, c_rit, c_xit, c_mode, c_vfo,
c_tone, tone, c_rptr_shift, cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
/* Set Memory Channel */
err = newcat_set_cmd(rig);
if (err != RIG_OK)
{
return err;
}
/* Restore VFO ********************************** */
if (restore_vfo)
{
err = newcat_vfomem_toggle(rig);
return err;
}
return RIG_OK;
}
int newcat_get_channel(RIG *rig, channel_t *chan)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
char *retval;
char c, c2;
int err, i;
chan_t *chan_list;
channel_cap_t *mem_caps = NULL;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "MR"))
{
return -RIG_ENAVAIL;
}
chan_list = rig->caps->chan_list;
for (i = 0; i < CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++)
{
if (chan->channel_num >= chan_list[i].startc &&
chan->channel_num <= chan_list[i].endc)
{
mem_caps = &chan_list[i].mem_caps;
break;
}
}
/* Out of Range */
if (!mem_caps)
{
return -RIG_ENAVAIL;
}
rig_debug(RIG_DEBUG_TRACE, "sizeof(channel_t) = %d\n", (int)sizeof(channel_t));
rig_debug(RIG_DEBUG_TRACE, "sizeof(priv->cmd_str) = %d\n",
(int)sizeof(priv->cmd_str));
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "MR%03d%c", chan->channel_num,
cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
/* Get Memory Channel */
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
if (-RIG_ERJCTED == err)
{
/* Invalid channel, has not been set up, make sure freq is
0 to indicate empty channel */
chan->freq = 0.;
return RIG_OK;
}
return err;
}
/* ret_data string to channel_t struct :: this will destroy ret_data */
/* rptr_shift P10 ************************ */
retval = priv->ret_data + 25;
switch (*retval)
{
case '0': chan->rptr_shift = RIG_RPT_SHIFT_NONE; break;
case '1': chan->rptr_shift = RIG_RPT_SHIFT_PLUS; break;
case '2': chan->rptr_shift = RIG_RPT_SHIFT_MINUS; break;
default: chan->rptr_shift = RIG_RPT_SHIFT_NONE;
}
*retval = '\0';
/* CTCSS Encoding P8 ********************* */
retval = priv->ret_data + 22;
c = *retval;
/* CTCSS Tone P9 ************************* */
chan->ctcss_tone = 0;
chan->ctcss_sql = 0;
retval = priv->ret_data + 23;
i = atoi(retval);
if (c == '1')
{
chan->ctcss_sql = rig->caps->ctcss_list[i];
}
else if (c == '2')
{
chan->ctcss_tone = rig->caps->ctcss_list[i];
}
/* vfo, mem, P7 ************************** */
retval = priv->ret_data + 21;
if (*retval == '1')
{
chan->vfo = RIG_VFO_MEM;
}
else
{
chan->vfo = RIG_VFO_CURR;
}
/* MODE P6 ******************************* */
chan->width = 0;
retval = priv->ret_data + 20;
switch (*retval)
{
case '1': chan->mode = RIG_MODE_LSB; break;
case '2': chan->mode = RIG_MODE_USB; break;
case '3': chan->mode = RIG_MODE_CW; break;
case '4': chan->mode = RIG_MODE_FM; break;
case '5': chan->mode = RIG_MODE_AM; break;
case '6': chan->mode = RIG_MODE_RTTY; break;
case '7': chan->mode = RIG_MODE_CWR; break;
case '8': chan->mode = RIG_MODE_PKTLSB; break;
case '9': chan->mode = RIG_MODE_RTTYR; break;
case 'A': chan->mode = RIG_MODE_PKTFM; break;
case 'B': chan->mode = RIG_MODE_FM; break;
case 'C': chan->mode = RIG_MODE_PKTUSB; break;
case 'D': chan->mode = RIG_MODE_AM; break;
2020-01-15 14:15:29 +00:00
case 'E': chan->mode = RIG_MODE_C4FM; break;
2020-02-23 17:26:09 +00:00
default:
rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%c\n", __func__, *retval);
2020-01-15 14:15:29 +00:00
chan->mode = RIG_MODE_LSB;
2019-11-30 16:19:08 +00:00
}
/* Clarifier TX P5 *********************** */
retval = priv->ret_data + 19;
c2 = *retval;
/* Clarifier RX P4 *********************** */
retval = priv->ret_data + 18;
c = *retval;
*retval = '\0';
/* Clarifier Offset P3 ******************* */
chan->rit = 0;
chan->xit = 0;
retval = priv->ret_data + 13;
2019-11-30 16:19:08 +00:00
if (c == '1')
{
chan->rit = atoi(retval);
}
else if (c2 == '1')
{
chan->xit = atoi(retval);
}
2019-11-30 16:19:08 +00:00
*retval = '\0';
2019-11-30 16:19:08 +00:00
/* Frequency P2 ************************** */
retval = priv->ret_data + 5;
chan->freq = atof(retval);
2019-11-30 16:19:08 +00:00
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
const char *newcat_get_info(RIG *rig)
{
2019-11-30 16:19:08 +00:00
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
static char idbuf[129]; /* extra large static string array */
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2019-11-30 16:19:08 +00:00
/* Build the command string */
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "ID;");
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
2019-11-30 16:19:08 +00:00
/* Get Identification Channel */
if (RIG_OK != newcat_get_cmd(rig))
2019-11-30 16:19:08 +00:00
{
return NULL;
}
2019-11-30 16:19:08 +00:00
priv->ret_data[6] = '\0';
snprintf(idbuf, sizeof(idbuf), "%s", priv->ret_data);
2019-11-30 16:19:08 +00:00
return idbuf;
}
2019-11-30 16:19:08 +00:00
/*
* newcat_valid_command
*
* Determine whether or not the command is valid for the specified
* rig. This function should be called before sending the command
* to the rig to make it easier to differentiate invalid and illegal
* commands (for a rig).
*/
ncboolean newcat_valid_command(RIG *rig, char const *const command)
{
2019-11-30 16:19:08 +00:00
const struct rig_caps *caps;
ncboolean is_ft450;
ncboolean is_ft891;
ncboolean is_ft950;
ncboolean is_ft991;
ncboolean is_ft2000;
ncboolean is_ft9000;
ncboolean is_ft5000;
ncboolean is_ft1200;
ncboolean is_ft3000;
ncboolean is_ft101;
int search_high;
int search_low;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s %s\n", __func__, command);
2019-11-30 16:19:08 +00:00
caps = rig->caps;
2019-11-30 16:19:08 +00:00
if (!caps)
{
rig_debug(RIG_DEBUG_ERR, "%s: Rig capabilities not valid\n", __func__);
return FALSE;
}
2019-11-30 16:19:08 +00:00
/*
* Determine the type of rig from the model number. Note it is
* possible for several model variants to exist; i.e., all the
* FT-9000 variants.
*/
2019-11-30 16:19:08 +00:00
is_ft450 = newcat_is_rig(rig, RIG_MODEL_FT450);
is_ft891 = newcat_is_rig(rig, RIG_MODEL_FT891);
is_ft950 = newcat_is_rig(rig, RIG_MODEL_FT950);
is_ft991 = newcat_is_rig(rig, RIG_MODEL_FT991);
is_ft2000 = newcat_is_rig(rig, RIG_MODEL_FT2000);
is_ft9000 = newcat_is_rig(rig, RIG_MODEL_FT9000);
is_ft5000 = newcat_is_rig(rig, RIG_MODEL_FTDX5000);
is_ft1200 = newcat_is_rig(rig, RIG_MODEL_FT1200);
is_ft3000 = newcat_is_rig(rig, RIG_MODEL_FTDX3000);
is_ft101 = newcat_is_rig(rig, RIG_MODEL_FTDX101D);
2019-11-30 16:19:08 +00:00
if (!is_ft450 && !is_ft950 && !is_ft891 && !is_ft991 && !is_ft2000
&& !is_ft5000 && !is_ft9000 && !is_ft1200 && !is_ft3000 && !is_ft101)
{
rig_debug(RIG_DEBUG_ERR, "%s: '%s' is unknown\n",
__func__, caps->model_name);
return FALSE;
}
2019-11-30 16:19:08 +00:00
/*
* Make sure the command is known, and then check to make sure
* is it valud for the rig.
*/
2019-11-30 16:19:08 +00:00
search_low = 0;
search_high = valid_commands_count;
2019-11-30 16:19:08 +00:00
while (search_low <= search_high)
{
int search_test;
2019-12-24 16:00:45 +00:00
int search_index;
2019-11-30 16:19:08 +00:00
search_index = (search_low + search_high) / 2;
search_test = strcmp(valid_commands[search_index].command, command);
2019-11-30 16:19:08 +00:00
if (search_test > 0)
{
search_high = search_index - 1;
}
else if (search_test < 0)
{
search_low = search_index + 1;
}
else
{
/*
* The command is valid. Now make sure it is supported by the rig.
*/
if (is_ft450 && valid_commands[search_index].ft450)
{
return TRUE;
}
else if (is_ft891 && valid_commands[search_index].ft891)
{
return TRUE;
}
else if (is_ft950 && valid_commands[search_index].ft950)
{
return TRUE;
}
else if (is_ft991 && valid_commands[search_index].ft991)
{
return TRUE;
}
else if (is_ft2000 && valid_commands[search_index].ft2000)
{
return TRUE;
}
else if (is_ft5000 && valid_commands[search_index].ft5000)
{
return TRUE;
}
else if (is_ft9000 && valid_commands[search_index].ft9000)
{
return TRUE;
}
else if (is_ft1200 && valid_commands[search_index].ft1200)
{
return TRUE;
}
else if (is_ft3000 && valid_commands[search_index].ft3000)
{
return TRUE;
}
else if (is_ft101 && valid_commands[search_index].ft101)
{
return TRUE;
}
else
{
rig_debug(RIG_DEBUG_TRACE, "%s: '%s' command '%s' not supported\n",
__func__, caps->model_name, command);
return FALSE;
}
}
}
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: '%s' command '%s' not valid\n",
__func__, caps->model_name, command);
return FALSE;
}
2019-11-30 16:19:08 +00:00
ncboolean newcat_is_rig(RIG *rig, rig_model_t model)
{
2019-11-30 16:19:08 +00:00
ncboolean is_rig;
2019-11-30 16:19:08 +00:00
is_rig = (model == rig->caps->rig_model) ? TRUE : FALSE;
return is_rig;
}
2019-11-30 16:19:08 +00:00
/*
* newcat_set_tx_vfo does not set priv->curr_vfo
*/
int newcat_set_tx_vfo(RIG *rig, vfo_t tx_vfo)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
2019-11-30 16:19:08 +00:00
int err;
char p1;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2019-11-30 16:19:08 +00:00
if (!newcat_valid_command(rig, "FT"))
{
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
err = newcat_set_vfo_from_alias(rig, &tx_vfo);
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
}
2019-11-30 16:19:08 +00:00
switch (tx_vfo)
{
case RIG_VFO_A:
p1 = '0';
break;
2019-11-30 16:19:08 +00:00
case RIG_VFO_B:
p1 = '1';
break;
2019-11-30 16:19:08 +00:00
case RIG_VFO_MEM:
/* VFO A */
if (priv->current_mem == NC_MEM_CHANNEL_NONE)
{
return RIG_OK;
}
else /* Memory Channel mode */
{
p1 = '0';
}
break;
2019-11-30 16:19:08 +00:00
default:
return -RIG_EINVAL;
}
2019-11-30 16:19:08 +00:00
/* TODO: G4WJS - FT-450 only has toggle command so not sure how to
definitively set the TX VFO (VS; doesn't seem to help
either) */
if (newcat_is_rig(rig, RIG_MODEL_FT950) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000) ||
newcat_is_rig(rig, RIG_MODEL_FT1200) ||
newcat_is_rig(rig, RIG_MODEL_FT991) ||
newcat_is_rig(rig, RIG_MODEL_FTDX3000))
{
p1 = p1 + 2; /* use non-Toggle commands */
}
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", "FT", p1, cat_term);
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str);
/* Set TX VFO */
return newcat_set_cmd(rig);
}
2019-11-30 16:19:08 +00:00
/*
* newcat_get_tx_vfo does not set priv->curr_vfo
*/
int newcat_get_tx_vfo(RIG *rig, vfo_t *tx_vfo)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
2019-11-30 16:19:08 +00:00
char c;
vfo_t vfo_mode;
char const *command = "FT";
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2019-11-30 16:19:08 +00:00
if (!newcat_valid_command(rig, command))
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term);
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str);
2019-11-30 16:19:08 +00:00
/* Get TX VFO */
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
c = priv->ret_data[2];
2019-11-30 16:19:08 +00:00
switch (c)
{
case '0':
*tx_vfo = RIG_VFO_A;
break;
2019-11-30 16:19:08 +00:00
case '1' :
*tx_vfo = RIG_VFO_B;
break;
2019-11-30 16:19:08 +00:00
default:
rig_debug(RIG_DEBUG_ERR, "%s: Unknown tx_vfo=%c from index 2 of %s\n", __func__,
c, priv->ret_data);
return -RIG_EPROTO;
}
2019-11-30 16:19:08 +00:00
/* Check to see if RIG is in MEM mode */
err = newcat_get_vfo_mode(rig, &vfo_mode);
2020-02-23 17:26:09 +00:00
if (err != RIG_OK)
{
return err;
}
2019-11-30 16:19:08 +00:00
if (vfo_mode == RIG_VFO_MEM && *tx_vfo == RIG_VFO_A)
{
*tx_vfo = RIG_VFO_MEM;
}
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = %s\n", __func__, rig_strvfo(*tx_vfo));
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_set_vfo_from_alias(RIG *rig, vfo_t *vfo)
{
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: alias vfo = %s\n", __func__, rig_strvfo(*vfo));
2019-11-30 16:19:08 +00:00
switch (*vfo)
{
case RIG_VFO_A:
case RIG_VFO_B:
case RIG_VFO_MEM:
/* passes through */
break;
2019-11-30 16:19:08 +00:00
case RIG_VFO_CURR: /* RIG_VFO_RX == RIG_VFO_CURR */
case RIG_VFO_VFO:
*vfo = rig->state.current_vfo;
break;
2019-11-30 16:19:08 +00:00
case RIG_VFO_TX:
/* set to another vfo for split or uplink */
*vfo = (rig->state.current_vfo == RIG_VFO_B) ? RIG_VFO_A : RIG_VFO_B;
break;
2019-11-30 16:19:08 +00:00
case RIG_VFO_MAIN:
*vfo = RIG_VFO_A;
break;
2019-11-30 16:19:08 +00:00
case RIG_VFO_SUB:
*vfo = RIG_VFO_B;
break;
2019-11-30 16:19:08 +00:00
default:
2020-03-20 12:51:32 +00:00
rig_debug(RIG_DEBUG_TRACE, "Unrecognized. vfo= %s\n", rig_strvfo(*vfo));
2019-11-30 16:19:08 +00:00
return -RIG_EINVAL;
}
2019-11-30 16:19:08 +00:00
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
/*
* Found newcat_set_level() floating point math problem
* Using rigctl on FT950 I was trying to set RIG_LEVEL_COMP to 12
* I kept setting it to 11. I wrote some test software and
* found out that 0.12 * 100 = 11 with my setup.
* Compilier is gcc 4.2.4, CPU is AMD X2
* This works somewhat but Find a better way.
* The newcat_get_level() seems to work correctly.
* Terry KJ4EED
*
*/
int newcat_scale_float(int scale, float fval)
{
float f;
float fudge = 0.003;
if ((fval + fudge) > 1.0)
{
f = scale * fval;
}
else
{
f = scale * (fval + fudge);
}
return (int) f;
}
2019-11-30 16:19:08 +00:00
int newcat_set_narrow(RIG *rig, vfo_t vfo, ncboolean narrow)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char c;
2019-11-30 16:19:08 +00:00
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2019-11-30 16:19:08 +00:00
if (!newcat_valid_command(rig, "NA"))
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
err = newcat_set_vfo_from_alias(rig, &vfo);
if (err < 0)
{
return err;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX3000))
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
}
2019-11-30 16:19:08 +00:00
if (narrow == TRUE)
{
c = '1';
}
else
{
c = '0';
}
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "NA%c%c%c", main_sub_vfo, c,
cat_term);
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str);
2019-11-30 16:19:08 +00:00
return newcat_set_cmd(rig);
}
2019-11-30 16:19:08 +00:00
int newcat_get_narrow(RIG *rig, vfo_t vfo, ncboolean *narrow)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
2019-11-30 16:19:08 +00:00
int err;
char c;
char command[] = "NA";
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2019-11-30 16:19:08 +00:00
if (!newcat_valid_command(rig, command))
{
return -RIG_ENAVAIL;
}
2019-11-30 16:19:08 +00:00
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
{
return err;
}
2019-11-30 16:19:08 +00:00
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FT2000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX3000))
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
}
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, main_sub_vfo,
cat_term);
2019-11-30 16:19:08 +00:00
/* Get NAR */
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
c = priv->ret_data[3];
if (c == '1')
{
*narrow = TRUE;
}
else
{
*narrow = FALSE;
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
2019-11-30 16:19:08 +00:00
int err;
char width_str[6]; /* extra larger buffer */
char main_sub_vfo = '0';
char narrow = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s vfo=%s, mode=%s, width=%d\n", __func__,
rig_strvfo(vfo), rig_strrmode(mode), (int)width);
2019-11-30 16:19:08 +00:00
if (!newcat_valid_command(rig, "SH"))
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
{
return err;
}
2019-11-30 16:19:08 +00:00
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX5000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX3000))
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
}
2019-11-30 16:19:08 +00:00
if (newcat_is_rig(rig, RIG_MODEL_FT950))
{
switch (mode)
{
case RIG_MODE_PKTUSB:
case RIG_MODE_PKTLSB:
case RIG_MODE_RTTY:
case RIG_MODE_RTTYR:
case RIG_MODE_CW:
case RIG_MODE_CWR:
switch (width)
{
case 1700: snprintf(width_str, sizeof(width_str), "11"); narrow = '0';
break; /* normal */
2019-11-30 16:19:08 +00:00
case 500: snprintf(width_str, sizeof(width_str), "07"); narrow = '0';
break; /* narrow */
2019-11-30 16:19:08 +00:00
case 2400: snprintf(width_str, sizeof(width_str), "13"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 2000: snprintf(width_str, sizeof(width_str), "12"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 1400: snprintf(width_str, sizeof(width_str), "10"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 1200: snprintf(width_str, sizeof(width_str), "09"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 800: snprintf(width_str, sizeof(width_str), "08"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 400: snprintf(width_str, sizeof(width_str), "06"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 300: snprintf(width_str, sizeof(width_str), "05"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 200: snprintf(width_str, sizeof(width_str), "04"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 100: snprintf(width_str, sizeof(width_str), "03"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
default: return -RIG_EINVAL;
}
2019-11-30 16:19:08 +00:00
break;
2019-11-30 16:19:08 +00:00
case RIG_MODE_LSB:
case RIG_MODE_USB:
switch (width)
{
case 2400: snprintf(width_str, sizeof(width_str), "13"); narrow = '0';
break; /* normal */
2019-11-30 16:19:08 +00:00
case 1800: snprintf(width_str, sizeof(width_str), "09"); narrow = '0';
break; /* narrow */
2019-11-30 16:19:08 +00:00
case 3000: snprintf(width_str, sizeof(width_str), "20"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 2900: snprintf(width_str, sizeof(width_str), "19"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2800: snprintf(width_str, sizeof(width_str), "18"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2700: snprintf(width_str, sizeof(width_str), "17"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2600: snprintf(width_str, sizeof(width_str), "16"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2500: snprintf(width_str, sizeof(width_str), "15"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2450: snprintf(width_str, sizeof(width_str), "14"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2250: snprintf(width_str, sizeof(width_str), "12"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2100: snprintf(width_str, sizeof(width_str), "11"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 1950: snprintf(width_str, sizeof(width_str), "10"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 1650: snprintf(width_str, sizeof(width_str), "08"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 1500: snprintf(width_str, sizeof(width_str), "07"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 1350: snprintf(width_str, sizeof(width_str), "06"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 1100: snprintf(width_str, sizeof(width_str), "05"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 850: snprintf(width_str, sizeof(width_str), "04"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 600: snprintf(width_str, sizeof(width_str), "03"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 400: snprintf(width_str, sizeof(width_str), "02"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 200: snprintf(width_str, sizeof(width_str), "01"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
default: return -RIG_EINVAL;
}
2019-11-30 16:19:08 +00:00
break;
2019-11-30 16:19:08 +00:00
case RIG_MODE_AM:
case RIG_MODE_FM:
case RIG_MODE_PKTFM:
if (width < rig_passband_normal(rig, mode))
{
err = newcat_set_narrow(rig, vfo, TRUE);
}
else
{
err = newcat_set_narrow(rig, vfo, FALSE);
}
2019-11-30 16:19:08 +00:00
return err;
2019-11-30 16:19:08 +00:00
default:
return -RIG_EINVAL;
} /* end switch(mode) */
} /* end if FT950 */
else if (newcat_is_rig(rig, RIG_MODEL_FT991)
|| newcat_is_rig(rig, RIG_MODEL_FT891))
{
switch (mode)
{
case RIG_MODE_PKTUSB:
case RIG_MODE_PKTLSB:
case RIG_MODE_RTTY:
case RIG_MODE_RTTYR:
case RIG_MODE_CW:
case RIG_MODE_CWR:
switch (width) // the defaults can be different for CW and RTTY (e.g. FT991) but I don't think it matters here
{
case 1700: snprintf(width_str, sizeof(width_str), "14"); narrow = '0';
break; /* normal */
2019-11-30 16:19:08 +00:00
case 500: snprintf(width_str, sizeof(width_str), "10"); narrow = '0';
break; /* narrow */
2019-11-30 16:19:08 +00:00
case 3000: snprintf(width_str, sizeof(width_str), "17"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 2400: snprintf(width_str, sizeof(width_str), "16"); narrow = '0'; break;
case 2000: snprintf(width_str, sizeof(width_str), "15"); narrow = '0'; break;
case 1400: snprintf(width_str, sizeof(width_str), "13"); narrow = '0'; break;
case 1200: snprintf(width_str, sizeof(width_str), "12"); narrow = '0'; break;
case 800: snprintf(width_str, sizeof(width_str), "11"); narrow = '0'; break;
case 450: snprintf(width_str, sizeof(width_str), "09"); narrow = '1'; break;
case 400: snprintf(width_str, sizeof(width_str), "08"); narrow = '1'; break;
case 350: snprintf(width_str, sizeof(width_str), "07"); narrow = '1'; break;
case 300: snprintf(width_str, sizeof(width_str), "06"); narrow = '1'; break;
case 250: snprintf(width_str, sizeof(width_str), "05"); narrow = '1'; break;
case 200: snprintf(width_str, sizeof(width_str), "04"); narrow = '1'; break;
case 150: snprintf(width_str, sizeof(width_str), "03"); narrow = '1'; break;
case 100: snprintf(width_str, sizeof(width_str), "02"); narrow = '1'; break;
case 50: snprintf(width_str, sizeof(width_str), "01"); narrow = '1'; break;
default: return -RIG_EINVAL;
}
2019-11-30 16:19:08 +00:00
break;
2019-11-30 16:19:08 +00:00
case RIG_MODE_LSB:
case RIG_MODE_USB:
switch (width)
{
case 2400: snprintf(width_str, sizeof(width_str), "14"); narrow = '0';
break; /* normal */
2019-11-30 16:19:08 +00:00
case 1500: snprintf(width_str, sizeof(width_str), "07"); narrow = '0';
break; /* narrow */
2019-11-30 16:19:08 +00:00
case 3200: snprintf(width_str, sizeof(width_str), "21"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 3000: snprintf(width_str, sizeof(width_str), "20"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2900: snprintf(width_str, sizeof(width_str), "19"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2800: snprintf(width_str, sizeof(width_str), "18"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2700: snprintf(width_str, sizeof(width_str), "17"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2600: snprintf(width_str, sizeof(width_str), "16"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2500: snprintf(width_str, sizeof(width_str), "15"); narrow = '0'; break;
case 2250: snprintf(width_str, sizeof(width_str), "12"); narrow = '0'; break;
case 2100: snprintf(width_str, sizeof(width_str), "11"); narrow = '0'; break;
case 1950: snprintf(width_str, sizeof(width_str), "10"); narrow = '0'; break;
case 1800: snprintf(width_str, sizeof(width_str), "09"); narrow = '0'; break;
case 1650: snprintf(width_str, sizeof(width_str), "08"); narrow = '1'; break;
case 1350: snprintf(width_str, sizeof(width_str), "06"); narrow = '1'; break;
case 1100: snprintf(width_str, sizeof(width_str), "05"); narrow = '1'; break;
case 850: snprintf(width_str, sizeof(width_str), "04"); narrow = '1'; break;
case 600: snprintf(width_str, sizeof(width_str), "03"); narrow = '1'; break;
case 400: snprintf(width_str, sizeof(width_str), "02"); narrow = '1'; break;
case 200: snprintf(width_str, sizeof(width_str), "01"); narrow = '1'; break;
default: return -RIG_EINVAL;
}
break;
2019-11-30 16:19:08 +00:00
case RIG_MODE_AM:
//case RIG_MODE_FM: // Can you set passband on FM or FMN for FT991? Returns error for now.
case RIG_MODE_PKTFM:
if (width < rig_passband_normal(rig, mode))
{
err = newcat_set_narrow(rig, vfo, TRUE);
}
else
{
err = newcat_set_narrow(rig, vfo, FALSE);
}
return err;
default:
return -RIG_EINVAL;
2019-11-30 16:19:08 +00:00
} /* end switch(mode) */
} /* end if FT991 */
else if (newcat_is_rig(rig, RIG_MODEL_FT1200))
{
switch (mode)
{
case RIG_MODE_PKTUSB:
case RIG_MODE_PKTLSB:
case RIG_MODE_RTTY:
case RIG_MODE_RTTYR:
case RIG_MODE_CW:
case RIG_MODE_CWR:
switch (width)
{
case 2400: snprintf(width_str, sizeof(width_str), "16"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 2000: snprintf(width_str, sizeof(width_str), "15"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 1700: snprintf(width_str, sizeof(width_str), "14"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 1400: snprintf(width_str, sizeof(width_str), "13"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 1200: snprintf(width_str, sizeof(width_str), "12"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 800: snprintf(width_str, sizeof(width_str), "11"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 500: snprintf(width_str, sizeof(width_str), "10"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 450: snprintf(width_str, sizeof(width_str), "09"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 400: snprintf(width_str, sizeof(width_str), "08"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 350: snprintf(width_str, sizeof(width_str), "07"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 300: snprintf(width_str, sizeof(width_str), "06"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 250: snprintf(width_str, sizeof(width_str), "05"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 200: snprintf(width_str, sizeof(width_str), "04"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 150: snprintf(width_str, sizeof(width_str), "03"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 100: snprintf(width_str, sizeof(width_str), "02"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 50: snprintf(width_str, sizeof(width_str), "01"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
default: return -RIG_EINVAL;
}
break;
2019-11-30 16:19:08 +00:00
case RIG_MODE_LSB:
case RIG_MODE_USB:
switch (width)
{
case 2300: snprintf(width_str, sizeof(width_str), "13"); narrow = '0';
break; /* normal */
2019-11-30 16:19:08 +00:00
case 1800: snprintf(width_str, sizeof(width_str), "09"); narrow = '0';
break; /* narrow */
2019-11-30 16:19:08 +00:00
case 3000: snprintf(width_str, sizeof(width_str), "20"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 3200: snprintf(width_str, sizeof(width_str), "21"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 3400: snprintf(width_str, sizeof(width_str), "22"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 3600: snprintf(width_str, sizeof(width_str), "23"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 3800: snprintf(width_str, sizeof(width_str), "24"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 4000: snprintf(width_str, sizeof(width_str), "25"); narrow = '0';
break; /* wide */
2019-11-30 16:19:08 +00:00
case 2900: snprintf(width_str, sizeof(width_str), "19"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2800: snprintf(width_str, sizeof(width_str), "18"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2700: snprintf(width_str, sizeof(width_str), "17"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2600: snprintf(width_str, sizeof(width_str), "16"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2500: snprintf(width_str, sizeof(width_str), "15"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2400: snprintf(width_str, sizeof(width_str), "14"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2200: snprintf(width_str, sizeof(width_str), "12"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 2100: snprintf(width_str, sizeof(width_str), "11"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 1950: snprintf(width_str, sizeof(width_str), "10"); narrow = '0'; break;
2019-11-30 16:19:08 +00:00
case 1650: snprintf(width_str, sizeof(width_str), "08"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 1500: snprintf(width_str, sizeof(width_str), "07"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 1350: snprintf(width_str, sizeof(width_str), "06"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 1100: snprintf(width_str, sizeof(width_str), "05"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 850: snprintf(width_str, sizeof(width_str), "04"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 600: snprintf(width_str, sizeof(width_str), "03"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 400: snprintf(width_str, sizeof(width_str), "02"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
case 200: snprintf(width_str, sizeof(width_str), "01"); narrow = '1'; break;
2019-11-30 16:19:08 +00:00
default: return -RIG_EINVAL;
}
2019-11-30 16:19:08 +00:00
break;
2019-11-30 16:19:08 +00:00
case RIG_MODE_AM:
case RIG_MODE_FM:
case RIG_MODE_PKTFM:
if (width < rig_passband_normal(rig, mode))
{
err = newcat_set_narrow(rig, vfo, TRUE);
}
else
{
err = newcat_set_narrow(rig, vfo, FALSE);
}
2019-11-30 16:19:08 +00:00
return err;
2019-11-30 16:19:08 +00:00
default:
return -RIG_EINVAL;
} /* end switch(mode) */
2019-11-30 16:19:08 +00:00
}
else /* end if FT1200 */
{
/* FT450, FT2000, FT5000, FT9000 */
2019-11-30 16:19:08 +00:00
switch (mode)
{
case RIG_MODE_PKTUSB:
case RIG_MODE_PKTLSB:
case RIG_MODE_RTTY:
case RIG_MODE_RTTYR:
case RIG_MODE_CW:
case RIG_MODE_CWR:
switch (width)
{
case 1800: snprintf(width_str, sizeof(width_str), "16"); narrow = '0';
break; /* normal */
case 500: snprintf(width_str, sizeof(width_str), "06"); narrow = '0';
break; /* narrow */
case 2400: snprintf(width_str, sizeof(width_str), "24"); narrow = '0';
break; /* wide */
default: return -RIG_EINVAL;
}
break;
case RIG_MODE_LSB:
case RIG_MODE_USB:
switch (width)
{
case 2400: snprintf(width_str, sizeof(width_str), "16"); narrow = '0';
break; /* normal */
case 1800: snprintf(width_str, sizeof(width_str), "08"); narrow = '0';
break; /* narrow */
case 3000: snprintf(width_str, sizeof(width_str), "25"); narrow = '0';
break; /* wide */
default: return -RIG_EINVAL;
}
break;
case RIG_MODE_AM:
case RIG_MODE_FM:
case RIG_MODE_PKTFM:
if (width < rig_passband_normal(rig, mode))
{
err = newcat_set_narrow(rig, vfo, TRUE);
}
else
{
err = newcat_set_narrow(rig, vfo, FALSE);
}
return err;
default:
return -RIG_EINVAL;
} /* end switch(mode) */
}
2019-11-30 16:19:08 +00:00
/* end else */
rig_debug(RIG_DEBUG_TRACE, "sizeof(width_str) = %d\n", (int)sizeof(width_str));
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "NA%c%c%cSH%c%s%c",
2019-11-30 16:19:08 +00:00
main_sub_vfo, narrow, cat_term, main_sub_vfo, width_str, cat_term);
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str);
/* Set RX Bandwidth */
return newcat_set_cmd(rig);
}
int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
int ret_data_len;
char *retlvl;
int w;
char cmd[] = "SH";
char main_sub_vfo = '0';
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, cmd))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
err = newcat_set_vfo_from_alias(rig, &vfo);
2019-11-30 16:19:08 +00:00
if (err < 0)
2019-11-30 16:19:08 +00:00
{
return err;
2019-11-30 16:19:08 +00:00
}
if (newcat_is_rig(rig, RIG_MODEL_FT9000) ||
2018-11-20 16:48:08 +00:00
newcat_is_rig(rig, RIG_MODEL_FTDX5000) ||
newcat_is_rig(rig, RIG_MODEL_FTDX3000))
2019-11-30 16:19:08 +00:00
{
main_sub_vfo = (RIG_VFO_B == vfo) ? '1' : '0';
2019-11-30 16:19:08 +00:00
}
2019-11-30 16:19:08 +00:00
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo,
cat_term);
/* Get RX BANDWIDTH */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
ret_data_len = strlen(priv->ret_data);
/* skip command */
2019-11-30 16:19:08 +00:00
retlvl = priv->ret_data + strlen(priv->cmd_str) - 1;
/* chop term */
2019-11-30 16:19:08 +00:00
priv->ret_data[ret_data_len - 1] = '\0';
w = atoi(retlvl); /* width */
2019-11-30 16:19:08 +00:00
if (newcat_is_rig(rig, RIG_MODEL_FT950))
{
switch (mode)
{
case RIG_MODE_PKTUSB:
case RIG_MODE_PKTLSB:
case RIG_MODE_RTTY:
case RIG_MODE_RTTYR:
case RIG_MODE_CW:
case RIG_MODE_CWR:
switch (w)
{
case 11: *width = 1700; break; /* normal */
case 0:
case 7: *width = 500; break; /* narrow */
case 13: *width = 2400; break; /* wide */
case 12: *width = 2000; break;
case 10: *width = 1400; break;
case 9: *width = 1200; break;
case 8: *width = 800; break;
case 6: *width = 400; break;
case 5: *width = 300; break;
case 3: *width = 100; break;
case 4: *width = 200; break;
default: return -RIG_EINVAL;
}
break;
case RIG_MODE_LSB:
case RIG_MODE_USB:
switch (w)
{
case 0:
case 13: *width = 2400; break; /* normal */
case 9: *width = 1800; break; /* narrow */
case 20: *width = 3000; break; /* wide */
case 19: *width = 2900; break;
case 18: *width = 2800; break;
case 17: *width = 2700; break;
case 16: *width = 2600; break;
case 15: *width = 2500; break;
case 14: *width = 2450; break;
case 12: *width = 2250; break;
case 11: *width = 2100; break;
case 10: *width = 1950; break;
case 8: *width = 1650; break;
case 7: *width = 1500; break;
case 6: *width = 1350; break;
case 5: *width = 1100; break;
case 4: *width = 850; break;
case 3: *width = 600; break;
case 2: *width = 400; break;
case 1: *width = 200; break;
default: return -RIG_EINVAL;
}
break;
case RIG_MODE_AM:
case RIG_MODE_PKTFM:
case RIG_MODE_FM:
return RIG_OK;
default:
return -RIG_EINVAL;
} /* end switch(mode) */
} /* end if FT950 */
2019-11-30 16:19:08 +00:00
else if (newcat_is_rig(rig, RIG_MODEL_FT1200))
{
switch (mode)
{
case RIG_MODE_PKTUSB:
case RIG_MODE_PKTLSB:
case RIG_MODE_RTTY:
case RIG_MODE_RTTYR:
case RIG_MODE_CW:
case RIG_MODE_CWR:
switch (w)
{
case 0:
case 10: *width = 500; break; /* narrow */
case 16: *width = 2400; break; /* wide */
case 15: *width = 2000; break; /* wide */
case 14: *width = 1700; break; /* wide */
case 13: *width = 1400; break; /* wide */
case 12: *width = 1200; break;
case 11: *width = 800; break;
case 9: *width = 450; break;
case 8: *width = 400; break;
case 7: *width = 350; break;
case 6: *width = 300; break;
case 5: *width = 250; break;
case 4: *width = 200; break;
case 3: *width = 150; break;
case 2: *width = 100; break;
case 1: *width = 50; break;
default: return -RIG_EINVAL;
}
break;
case RIG_MODE_LSB:
case RIG_MODE_USB:
switch (w)
{
case 0:
case 14: *width = 2400; break; /* normal */
case 9: *width = 1800; break; /* narrow */
case 25: *width = 4000; break; /* wide */
case 24: *width = 3800; break; /* wide */
case 23: *width = 3600; break; /* wide */
case 22: *width = 3400; break; /* wide */
case 21: *width = 3200; break; /* wide */
case 20: *width = 3000; break; /* wide */
case 19: *width = 2900; break;
case 18: *width = 2800; break;
case 17: *width = 2700; break;
case 16: *width = 2600; break;
case 15: *width = 2500; break;
case 13: *width = 2300; break;
case 12: *width = 2200; break;
case 11: *width = 2100; break;
case 10: *width = 1950; break;
case 8: *width = 1650; break;
case 7: *width = 1500; break;
case 6: *width = 1350; break;
case 5: *width = 1100; break;
case 4: *width = 850; break;
case 3: *width = 600; break;
case 2: *width = 400; break;
case 1: *width = 200; break;
default: return -RIG_EINVAL;
}
break;
case RIG_MODE_AM:
case RIG_MODE_PKTFM:
case RIG_MODE_FM:
return RIG_OK;
default:
return -RIG_EINVAL;
} /* end switch(mode) */
2019-11-30 16:19:08 +00:00
}
else /* end if FT950 */
{
/* FT450, FT2000, FT5000, FT9000 */
2019-11-30 16:19:08 +00:00
switch (mode)
{
case RIG_MODE_PKTUSB:
case RIG_MODE_PKTLSB:
case RIG_MODE_RTTY:
case RIG_MODE_RTTYR:
case RIG_MODE_CW:
case RIG_MODE_CWR:
case RIG_MODE_LSB:
case RIG_MODE_USB:
if (w < 16)
{
*width = rig_passband_narrow(rig, mode);
}
else if (w > 16)
{
*width = rig_passband_wide(rig, mode);
}
else
{
*width = rig_passband_normal(rig, mode);
}
break;
case RIG_MODE_AM:
case RIG_MODE_PKTFM:
case RIG_MODE_FM:
return RIG_OK;
default:
return -RIG_EINVAL;
} /* end switch (mode) */
} /* end else */
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_set_faststep(RIG *rig, ncboolean fast_step)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
char c;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, "FS"))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
if (fast_step == TRUE)
2019-11-30 16:19:08 +00:00
{
c = '1';
2019-11-30 16:19:08 +00:00
}
else
2019-11-30 16:19:08 +00:00
{
c = '0';
2019-11-30 16:19:08 +00:00
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "FS%c%c", c, cat_term);
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str);
return newcat_set_cmd(rig);
}
2019-11-30 16:19:08 +00:00
int newcat_get_faststep(RIG *rig, ncboolean *fast_step)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
char c;
char command[] = "FS";
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term);
2019-11-30 16:19:08 +00:00
/* Get Fast Step */
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
c = priv->ret_data[2];
2019-11-30 16:19:08 +00:00
if (c == '1')
2019-11-30 16:19:08 +00:00
{
*fast_step = TRUE;
2019-11-30 16:19:08 +00:00
}
else
2019-11-30 16:19:08 +00:00
{
*fast_step = FALSE;
2019-11-30 16:19:08 +00:00
}
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
int newcat_get_rigid(RIG *rig)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
2019-11-30 16:19:08 +00:00
const char *s = NULL;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
/* if first valid get */
2019-11-30 16:19:08 +00:00
if (priv->rig_id == NC_RIGID_NONE)
{
s = newcat_get_info(rig);
2019-11-30 16:19:08 +00:00
if (s != NULL)
{
s += 2; /* ID0310, jump past ID */
priv->rig_id = atoi(s);
}
}
2020-03-26 16:11:46 +00:00
rig_debug(RIG_DEBUG_TRACE, "rig_id = %d, *s = %s\n", priv->rig_id,
s == NULL ? "NULL" : s);
return priv->rig_id;
}
/*
* input: RIG *, vfo_t *
* output: VFO mode: RIG_VFO_VFO for VFO A and B
* RIG_VFO_MEM for VFO MEM
* return: RIG_OK or error
*/
2019-11-30 16:19:08 +00:00
int newcat_get_vfo_mode(RIG *rig, vfo_t *vfo_mode)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int err;
int offset = 0;
char command[] = "IF";
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
/* Get VFO A Information ****************** */
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term);
2019-11-30 16:19:08 +00:00
if (RIG_OK != (err = newcat_get_cmd(rig)))
{
return err;
2019-11-30 16:19:08 +00:00
}
/* vfo, mem, P7 ************************** */
// e.g. FT450 has 27 byte IF response, FT991 has 28 byte if response (one more byte for P2 VFO A Freq)
// so we now check to ensure we know the length of the response
2019-11-30 16:19:08 +00:00
switch (strlen(priv->ret_data))
{
case 27: offset = 21; priv->width_frequency = 8; break;
case 28: offset = 22; priv->width_frequency = 9; break;
default:
rig_debug(RIG_DEBUG_ERR,
"%s: incorrect length of IF response, expected 27 or 28, got %d", __func__,
(int)strlen(priv->ret_data));
2019-11-30 16:19:08 +00:00
return -RIG_EPROTO;
}
rig_debug(RIG_DEBUG_TRACE, "%s: offset=%d, width_frequeny=%d\n", __func__,
offset, priv->width_frequency);
switch (priv->ret_data[offset])
{
case '0': *vfo_mode = RIG_VFO_VFO; break;
case '1': /* Memory */
case '2': /* Memory Tune */
case '3': /* Quick Memory Bank */
case '4': /* Quick Memory Bank Tune */
default:
*vfo_mode = RIG_VFO_MEM;
}
2020-03-26 16:11:46 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: vfo mode = %s\n", __func__,
rig_strrmode(*vfo_mode));
return err;
}
/*
* Writed data and waits for responce
* input: complete CAT command string including termination in cmd_str
* output: complete CAT command answer string in ret_data
* return: RIG_OK or error
*/
2019-11-30 16:19:08 +00:00
int newcat_vfomem_toggle(RIG *rig)
{
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
char command[] = "VM";
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!newcat_valid_command(rig, command))
2019-11-30 16:19:08 +00:00
{
return -RIG_ENAVAIL;
2019-11-30 16:19:08 +00:00
}
/* copy set command */
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term);
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
return newcat_set_cmd(rig);
}
/*
* Writes a null terminated command string from priv->cmd_str to the
* CAT port and returns a response from the rig in priv->ret_data
* which is also null terminated.
*
* Honors the 'retry' capabilities field by resending the command up
* to 'retry' times until a valid response is received. In the special
* cases of receiving a valid response to a different command or the
* "?;" busy please wait response; the command is not resent but up to
* 'retry' retries to receive a valid response are made.
*/
2019-11-30 16:19:08 +00:00
int newcat_get_cmd(RIG *rig)
{
2019-11-30 16:19:08 +00:00
struct rig_state *state = &rig->state;
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int retry_count = 0;
int rc = -RIG_EPROTO;
2019-11-30 16:19:08 +00:00
while (rc != RIG_OK && retry_count++ <= state->rigport.retry)
{
2019-11-30 16:19:08 +00:00
if (rc != -RIG_BUSBUSY)
{
2019-11-30 16:19:08 +00:00
/* send the command */
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str);
if (RIG_OK != (rc = write_block(&state->rigport, priv->cmd_str,
strlen(priv->cmd_str))))
{
2019-11-30 16:19:08 +00:00
return rc;
}
}
2019-11-30 16:19:08 +00:00
/* read the reply */
if ((rc = read_string(&state->rigport, priv->ret_data, sizeof(priv->ret_data),
&cat_term, sizeof(cat_term))) <= 0)
{
2019-11-30 16:19:08 +00:00
continue; /* usually a timeout - retry */
}
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: read count = %d, ret_data = %s\n",
__func__, rc, priv->ret_data);
rc = RIG_OK; /* received something */
/* Check that command termination is correct - alternative is
response is longer that the buffer */
if (!strchr(&cat_term, priv->ret_data[strlen(priv->ret_data) - 1]))
{
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n",
__func__, priv->ret_data);
rc = -RIG_BUSBUSY; /* don't write command again */
/* we could decrement retry_count
here but there is a danger of
infinite looping so we just use up
a retry for safety's sake */
continue; /* retry */
}
2019-11-30 16:19:08 +00:00
/* check for error codes */
if (2 == strlen(priv->ret_data))
{
2019-11-30 16:19:08 +00:00
/* The following error responses are documented for Kenwood
but not for Yaesu, but at least one of them is known to
occur in that the FT-450 certainly responds to "IF;"
occasionally with "?;". The others are harmless even of
they do not occur as they are unambiguous. */
switch (priv->ret_data[0])
{
case 'N':
2019-11-30 16:19:08 +00:00
/* Command recognized by rig but invalid data entered. */
rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, priv->cmd_str);
return -RIG_ENAVAIL;
case 'O':
2019-11-30 16:19:08 +00:00
/* Too many characters sent without a carriage return */
rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__,
priv->cmd_str);
rc = -RIG_EPROTO;
break; /* retry */
case 'E':
2019-11-30 16:19:08 +00:00
/* Communication error */
rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__,
priv->cmd_str);
rc = -RIG_EIO;
break; /* retry */
case '?':
2019-11-30 16:19:08 +00:00
/* Rig busy wait please */
rig_debug(RIG_DEBUG_ERR, "%s: Rig busy\n", __func__);
rc = -RIG_BUSBUSY;
break; /* retry read only */
}
2019-11-30 16:19:08 +00:00
continue;
}
2019-11-30 16:19:08 +00:00
/* verify that reply was to the command we sent */
if ((priv->ret_data[0] != priv->cmd_str[0]
|| priv->ret_data[1] != priv->cmd_str[1]))
{
2019-11-30 16:19:08 +00:00
/*
* TODO: When RIG_TRN is enabled, we can pass the string
* to the decoder for callback. That way we don't ignore
* any commands.
*/
rig_debug(RIG_DEBUG_ERR, "%s: wrong reply %.2s for command %.2s\n",
__func__, priv->ret_data, priv->cmd_str);
rc = -RIG_BUSBUSY; /* retry read only */
}
}
2019-11-30 16:19:08 +00:00
return rc;
}
/*
* Writes a null terminated command string from priv->cmd_str to the
* CAT port that is not expected to have a response.
*
* Honors the 'retry' capabilities field by resending the command up
* to 'retry' times until a valid response is received. In the special
* cases of receiving a valid response to a different command or the
* "?;" busy please wait response; the command is not resent but up to
* 'retry' retries to receive a valid response are made.
*/
2019-11-30 16:19:08 +00:00
int newcat_set_cmd(RIG *rig)
{
2019-11-30 16:19:08 +00:00
struct rig_state *state = &rig->state;
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
int retry_count = 0;
int rc = -RIG_EPROTO;
2019-11-30 16:19:08 +00:00
/* pick a basic quick query command for verification */
char const *const verify_cmd = RIG_MODEL_FT9000 == rig->caps->rig_model ?
"AI;" : "ID;";
2019-11-30 16:19:08 +00:00
while (rc != RIG_OK && retry_count++ <= state->rigport.retry)
{
2019-11-30 16:19:08 +00:00
serial_flush(&state->rigport); /* discard any unsolicited data */
/* send the command */
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str);
if (RIG_OK != (rc = write_block(&state->rigport, priv->cmd_str,
strlen(priv->cmd_str))))
{
2019-11-30 16:19:08 +00:00
return rc;
}
2019-11-30 16:19:08 +00:00
/* skip validation if high throughput is needed */
if (priv->fast_set_commands == TRUE)
{
return RIG_OK;
}
2019-11-30 16:19:08 +00:00
/* send the verification command */
rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", verify_cmd);
if (RIG_OK != (rc = write_block(&state->rigport, verify_cmd,
strlen(verify_cmd))))
{
2019-11-30 16:19:08 +00:00
return rc;
}
2019-11-30 16:19:08 +00:00
/* read the reply */
if ((rc = read_string(&state->rigport, priv->ret_data, sizeof(priv->ret_data),
&cat_term, sizeof(cat_term))) <= 0)
{
2019-11-30 16:19:08 +00:00
continue; /* usually a timeout - retry */
}
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: read count = %d, ret_data = %s\n",
__func__, rc, priv->ret_data);
rc = RIG_OK; /* received something */
/* check for error codes */
if (2 == strlen(priv->ret_data))
{
2019-11-30 16:19:08 +00:00
/* The following error responses are documented for Kenwood
but not for Yaesu, but at least one of them is known to
occur in that the FT-450 certainly responds to "IF;"
occasionally with "?;". The others are harmless even of
they do not occur as they are unambiguous. */
switch (priv->ret_data[0])
{
case 'N':
2019-11-30 16:19:08 +00:00
/* Command recognized by rig but invalid data entered. */
rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, priv->cmd_str);
return -RIG_ENAVAIL;
case 'O':
2019-11-30 16:19:08 +00:00
/* Too many characters sent without a carriage return */
rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__,
priv->cmd_str);
rc = -RIG_EPROTO;
break; /* retry */
case 'E':
2019-11-30 16:19:08 +00:00
/* Communication error */
rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__,
priv->cmd_str);
rc = -RIG_EIO;
break; /* retry */
case '?':
2019-11-30 16:19:08 +00:00
/* Rig busy wait please */
rig_debug(RIG_DEBUG_WARN, "%s: Rig busy - retrying\n", __func__);
/* read the verify command reply */
if ((rc = read_string(&state->rigport, priv->ret_data, sizeof(priv->ret_data),
&cat_term, sizeof(cat_term))) > 0)
{
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_TRACE, "%s: read count = %d, ret_data = %s\n",
__func__, rc, priv->ret_data);
rc = RIG_OK; /* probably recovered and read verification */
}
2019-11-30 16:19:08 +00:00
else
{
2019-11-30 16:19:08 +00:00
/* probably a timeout */
rc = -RIG_BUSBUSY; /* retry */
}
2019-11-30 16:19:08 +00:00
break;
}
}
2019-11-30 16:19:08 +00:00
if (RIG_OK == rc)
{
2019-11-30 16:19:08 +00:00
/* Check that response prefix and response termination is
correct - alternative is response is longer that the
buffer */
if (strncmp(verify_cmd, priv->ret_data, strlen(verify_cmd) - 1)
|| !strchr(&cat_term, priv->ret_data[strlen(priv->ret_data) - 1]))
{
2019-11-30 16:19:08 +00:00
rig_debug(RIG_DEBUG_ERR, "%s: Unexpected verify command response '%s'\n",
__func__, priv->ret_data);
rc = -RIG_BUSBUSY;
continue; /* retry */
}
}
}
2019-11-30 16:19:08 +00:00
return rc;
}