2001-06-03 17:39:59 +00:00
|
|
|
/*
|
|
|
|
* hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com)
|
|
|
|
*
|
|
|
|
* alinco.c - Copyright (C) 2001 Stephane Fillod
|
|
|
|
* This shared library provides an API for communicating
|
|
|
|
* via serial interface to a Kenwood radio.
|
|
|
|
*
|
|
|
|
*
|
2001-06-27 17:32:47 +00:00
|
|
|
* $Id: alinco.c,v 1.4 2001-06-27 17:32:47 f4cfe Exp $
|
2001-06-03 17:39:59 +00:00
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h> /* Standard input/output definitions */
|
|
|
|
#include <string.h> /* String function definitions */
|
|
|
|
#include <unistd.h> /* UNIX standard function definitions */
|
|
|
|
#include <fcntl.h> /* File control definitions */
|
|
|
|
#include <errno.h> /* Error number definitions */
|
|
|
|
#include <termios.h> /* POSIX terminal control definitions */
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include <hamlib/rig.h>
|
|
|
|
#include <hamlib/riglist.h>
|
|
|
|
#include <serial.h>
|
|
|
|
#include <misc.h>
|
|
|
|
#include "alinco.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define EOM "\r"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* modes in use by the "2G" command
|
|
|
|
*/
|
|
|
|
#define MD_LSB '0'
|
|
|
|
#define MD_USB '1'
|
|
|
|
#define MD_CWL '2'
|
|
|
|
#define MD_CWU '3'
|
|
|
|
#define MD_AM '4'
|
|
|
|
#define MD_FM '5'
|
|
|
|
|
|
|
|
#define AL "AL"
|
|
|
|
#define CMD_TXFREQ "0A" /* Transmit frequency */
|
|
|
|
#define CMD_RXFREQ "0B" /* Receive frequency */
|
|
|
|
#define CMD_VFO "1A"
|
|
|
|
#define CMD_MEMMD "1B" /* Memory mode */
|
|
|
|
#define CMD_CHAN "1D" /* Channel Display */
|
|
|
|
#define CMD_UPDWN "2A" /* UP/DOWN */
|
|
|
|
#define CMD_MON "2B" /* Check Transmit Frequency */
|
|
|
|
#define CMD_PWR "2C" /* Transmit Output Power */
|
|
|
|
#define CMD_SCAN "2D" /* Scanning */
|
|
|
|
#define CMD_PRIO "2E" /* Priority */
|
|
|
|
#define CMD_SPLT "2F" /* Split */
|
|
|
|
#define CMD_MODE "2G" /* Mode */
|
|
|
|
#define CMD_RFGAIN "2H" /* RF Gain */
|
|
|
|
#define CMD_AGC "2I"
|
|
|
|
#define CMD_FLTER "2J" /* Filter */
|
|
|
|
#define CMD_NB "2K"
|
|
|
|
#define CMD_CTCSS "2L"
|
|
|
|
#define CMD_TUNE "2M"
|
|
|
|
#define CMD_SELECT "2N"
|
|
|
|
#define CMD_MCALL "2V" /* Memory Channel Call Up */
|
|
|
|
#define CMD_SDATA "2W" /* Set Data */
|
|
|
|
|
|
|
|
/* Data Output Commands */
|
|
|
|
#define CMD_SMETER "3A" /* S-meter read */
|
|
|
|
#define CMD_PTT "3B" /* PTT status read */
|
|
|
|
#define CMD_SQL "3C" /* Squelch status */
|
|
|
|
#define CMD_RIT "3D" /* RIT status */
|
|
|
|
#define CMD_RMEM "3E" /* Current Memory-channel Number read */
|
|
|
|
#define CMD_RMV "3G" /* Memory/VFO -mode read */
|
|
|
|
#define CMD_RDATA "3H" /* Current Data read */
|
|
|
|
#define CMD_RSPLT "3I" /* Split read */
|
|
|
|
#define CMD_RPOWER "3J" /* Transmitter Output read */
|
|
|
|
#define CMD_RSELECT "3K" /* SELECT Postion read */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_transaction
|
|
|
|
* We assume that rig!=NULL, rig->state!= NULL, data!=NULL, data_len!=NULL
|
|
|
|
* Otherwise, you'll get a nice seg fault. You've been warned!
|
|
|
|
* TODO: error case handling
|
|
|
|
*/
|
|
|
|
int alinco_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len)
|
|
|
|
{
|
2001-06-12 07:07:11 +00:00
|
|
|
int i, count, retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
struct rig_state *rs;
|
|
|
|
|
|
|
|
rs = &rig->state;
|
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = write_block(&rs->rigport, cmd, cmd_len);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
/* no data expected, TODO: flush input? */
|
|
|
|
if (!data || !data_len)
|
|
|
|
return 0;
|
|
|
|
/*
|
|
|
|
* buffered read are quite helpful here!
|
|
|
|
* However, an automate with a state model would be more efficient..
|
|
|
|
*/
|
|
|
|
i = 0;
|
|
|
|
do {
|
2001-06-04 17:01:21 +00:00
|
|
|
count = fread_block(&rs->rigport, data+i, 1);
|
2001-06-03 17:39:59 +00:00
|
|
|
if (count > 0)
|
|
|
|
i += count;
|
2001-06-12 07:07:11 +00:00
|
|
|
else if (count < 0)
|
|
|
|
return count;
|
2001-06-03 17:39:59 +00:00
|
|
|
} while (count > 0);
|
|
|
|
|
|
|
|
*data_len = i;
|
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
return RIG_OK;
|
2001-06-03 17:39:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_set_vfo
|
|
|
|
* Assumes rig!=NULL
|
|
|
|
*/
|
|
|
|
int alinco_set_vfo(RIG *rig, vfo_t vfo)
|
|
|
|
{
|
|
|
|
char cmdbuf[16];
|
|
|
|
int cmd_len;
|
|
|
|
char vfo_num;
|
|
|
|
|
|
|
|
switch (vfo) {
|
|
|
|
case RIG_VFO_A: vfo_num = '1'; break;
|
|
|
|
case RIG_VFO_B: vfo_num = '2'; break;
|
|
|
|
case RIG_VFO_MEM:
|
|
|
|
return alinco_transaction (rig, AL CMD_MEMMD "0" EOM,
|
|
|
|
strlen(AL CMD_MEMMD "0" EOM), NULL, NULL);
|
|
|
|
default:
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_set_vfo: unsupported VFO %d\n",
|
|
|
|
vfo);
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
}
|
|
|
|
cmd_len = sprintf(cmdbuf, AL CMD_VFO "%c" EOM, vfo_num);
|
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL);
|
2001-06-03 17:39:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_get_vfo
|
|
|
|
* Assumes rig!=NULL, !vfo
|
|
|
|
*/
|
|
|
|
int alinco_get_vfo(RIG *rig, vfo_t *vfo)
|
|
|
|
{
|
|
|
|
char vfobuf[16];
|
2001-06-12 07:07:11 +00:00
|
|
|
int vfo_len, retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction(rig, AL CMD_RMV EOM,
|
|
|
|
strlen(AL CMD_RMV EOM), vfobuf, &vfo_len);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
if (vfo_len != 4 || vfo_len != 6) {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_vfo: wrong answer %s, "
|
|
|
|
"len=%d\n", vfobuf, vfo_len);
|
|
|
|
return -RIG_ERJCTED;
|
|
|
|
}
|
|
|
|
vfobuf[vfo_len] = '\0';
|
|
|
|
|
|
|
|
if (!strcmp(vfobuf, "VFOA"))
|
|
|
|
*vfo = RIG_VFO_A;
|
|
|
|
else if (!strcmp(vfobuf, "VFOB"))
|
|
|
|
*vfo = RIG_VFO_B;
|
|
|
|
else if (!strcmp(vfobuf, "Memory") || !strcmp(vfobuf, "MEMO"))
|
|
|
|
*vfo = RIG_VFO_MEM;
|
|
|
|
else {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_vfo: unsupported VFO %s\n",
|
|
|
|
vfobuf);
|
|
|
|
return -RIG_EPROTO;
|
|
|
|
}
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_set_freq
|
|
|
|
* Assumes rig!=NULL
|
|
|
|
*/
|
|
|
|
int alinco_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
|
|
|
{
|
|
|
|
char freqbuf[16];
|
|
|
|
int freq_len;
|
|
|
|
|
|
|
|
/* max 10 digits */
|
|
|
|
if (freq >= GHz(10))
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
|
|
|
|
/* at least 6 digits */
|
|
|
|
freq_len = sprintf(freqbuf, AL CMD_RXFREQ "%06Ld" EOM, freq);
|
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
return alinco_transaction (rig, freqbuf, freq_len, NULL, NULL);
|
2001-06-03 17:39:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* where databuf points to a 26 char long buffer
|
|
|
|
*/
|
|
|
|
static int current_data_read(RIG *rig, char *databuf)
|
|
|
|
{
|
2001-06-12 07:07:11 +00:00
|
|
|
int data_len, retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction (rig, AL CMD_RDATA EOM,
|
|
|
|
strlen(AL CMD_RDATA EOM), databuf, &data_len);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
if (data_len != 26) {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_current_data_read: "
|
|
|
|
"wrong answer %s, len=%d\n", databuf, data_len);
|
|
|
|
return -RIG_ERJCTED;
|
|
|
|
}
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_get_freq
|
|
|
|
* Assumes rig!=NULL, freq!=NULL
|
|
|
|
*/
|
|
|
|
int alinco_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
|
|
|
{
|
|
|
|
int retval;
|
|
|
|
char freqbuf[32];
|
|
|
|
|
|
|
|
retval = current_data_read(rig, freqbuf);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
/* extract RX freq */
|
|
|
|
freqbuf[16] = '\0';
|
|
|
|
sscanf(freqbuf+6, "%Ld", freq);
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_set_mode
|
|
|
|
* Assumes rig!=NULL
|
|
|
|
*/
|
|
|
|
int alinco_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
|
|
|
{
|
|
|
|
char mdbuf[16];
|
2001-06-12 07:07:11 +00:00
|
|
|
int mdbuf_len, narrow_filter, retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
char amode;
|
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
/* FIXME: MD_CWL or MD_CWU? */
|
|
|
|
case RIG_MODE_CW: amode = MD_CWL; break;
|
|
|
|
case RIG_MODE_USB: amode = MD_USB; break;
|
|
|
|
case RIG_MODE_LSB: amode = MD_LSB; break;
|
|
|
|
case RIG_MODE_FM: amode = MD_FM; break;
|
|
|
|
case RIG_MODE_AM: amode = MD_AM; break;
|
|
|
|
default:
|
|
|
|
rig_debug(RIG_DEBUG_ERR,
|
|
|
|
"alinco_set_mode: unsupported mode %d\n",
|
|
|
|
mode);
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
mdbuf_len = sprintf(mdbuf, AL CMD_MODE "%c" EOM, amode);
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction (rig, mdbuf, mdbuf_len, NULL, NULL);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* TODO: please DX77 owners, check this, I'm not sure
|
|
|
|
* which passband is default!
|
|
|
|
*/
|
|
|
|
if (width != RIG_PASSBAND_NORMAL &&
|
|
|
|
width < rig_passband_normal(rig, mode))
|
|
|
|
narrow_filter = 1;
|
|
|
|
else
|
|
|
|
narrow_filter = 0;
|
|
|
|
|
|
|
|
mdbuf_len = sprintf(mdbuf, AL CMD_FLTER "%02d" EOM, narrow_filter);
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction (rig, mdbuf, mdbuf_len, NULL, NULL);
|
2001-06-03 17:39:59 +00:00
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_get_mode
|
|
|
|
* Assumes rig!=NULL, mode!=NULL
|
|
|
|
*/
|
|
|
|
int alinco_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
|
|
|
{
|
|
|
|
int retval;
|
|
|
|
int settings;
|
|
|
|
char modebuf[32];
|
|
|
|
|
|
|
|
retval = current_data_read(rig, modebuf);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
/* FIXME: CWL&CWU: what are they? CW & CWR? */
|
|
|
|
switch (modebuf[3]) {
|
|
|
|
case MD_CWL:
|
|
|
|
case MD_CWU: *mode = RIG_MODE_CW; break;
|
|
|
|
case MD_USB: *mode = RIG_MODE_USB; break;
|
|
|
|
case MD_LSB: *mode = RIG_MODE_LSB; break;
|
|
|
|
case MD_AM: *mode = RIG_MODE_AM; break;
|
|
|
|
case MD_FM: *mode = RIG_MODE_FM; break;
|
|
|
|
default:
|
|
|
|
rig_debug(RIG_DEBUG_ERR,
|
|
|
|
"alinco_get_mode: unknown mode %c%c\n",
|
|
|
|
modebuf[2],modebuf[3]);
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
}
|
|
|
|
modebuf[2] = '\0';
|
|
|
|
settings = strtol(modebuf, (char **)NULL, 16);
|
|
|
|
/*
|
|
|
|
* TODO: please DX77 owners, check this, I'm not sure
|
|
|
|
* which passband is default!
|
|
|
|
*/
|
|
|
|
if (settings & 0x02)
|
|
|
|
*width = rig_passband_narrow(rig, *mode);
|
|
|
|
else
|
|
|
|
*width = rig_passband_normal(rig, *mode);
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-06-04 17:01:21 +00:00
|
|
|
* alinco_set_split
|
2001-06-03 17:39:59 +00:00
|
|
|
* Assumes rig!=NULL
|
|
|
|
*/
|
2001-06-04 17:01:21 +00:00
|
|
|
int alinco_set_split(RIG *rig, vfo_t vfo, split_t split)
|
2001-06-03 17:39:59 +00:00
|
|
|
{
|
|
|
|
int cmd_len;
|
|
|
|
char cmdbuf[32];
|
|
|
|
|
|
|
|
cmd_len = sprintf(cmdbuf, AL CMD_SPLT "%d" EOM,
|
|
|
|
split==RIG_SPLIT_ON ? 1 : 0);
|
|
|
|
|
|
|
|
return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-06-04 17:01:21 +00:00
|
|
|
* alinco_get_split
|
2001-06-03 17:39:59 +00:00
|
|
|
* Assumes rig!=NULL, split!=NULL
|
|
|
|
*/
|
2001-06-04 17:01:21 +00:00
|
|
|
int alinco_get_split(RIG *rig, vfo_t vfo, split_t *split)
|
2001-06-03 17:39:59 +00:00
|
|
|
{
|
2001-06-12 07:07:11 +00:00
|
|
|
int splt_len, retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
char spltbuf[32];
|
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction (rig, AL CMD_RSPLT EOM,
|
|
|
|
strlen(AL CMD_RSPLT EOM), spltbuf, &splt_len);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
if (splt_len != 2) {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_split: wrong answer %s, "
|
|
|
|
"len=%d\n", spltbuf, splt_len);
|
|
|
|
return -RIG_ERJCTED;
|
|
|
|
}
|
|
|
|
spltbuf[splt_len] = '\0';
|
|
|
|
|
|
|
|
if (!strcmp(spltbuf, "OF"))
|
|
|
|
*split = RIG_SPLIT_OFF;
|
|
|
|
else if (!strcmp(spltbuf, "ON"))
|
|
|
|
*split = RIG_SPLIT_ON;
|
|
|
|
else {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_split: unsupported SPLIT %s\n",
|
|
|
|
spltbuf);
|
|
|
|
return -RIG_EPROTO;
|
|
|
|
}
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_set_split_freq
|
|
|
|
* Assumes rig!=NULL
|
|
|
|
*/
|
2001-06-27 17:32:47 +00:00
|
|
|
int alinco_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
|
2001-06-03 17:39:59 +00:00
|
|
|
{
|
|
|
|
char freqbuf[16];
|
|
|
|
int freq_len;
|
|
|
|
int retval;
|
|
|
|
|
|
|
|
/* max 10 digits */
|
|
|
|
if (tx_freq >= GHz(10))
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
|
|
|
|
/* at least 6 digits */
|
|
|
|
freq_len = sprintf(freqbuf, AL CMD_TXFREQ "%06Ld" EOM, tx_freq);
|
|
|
|
|
|
|
|
retval = alinco_transaction (rig, freqbuf, freq_len, NULL, NULL);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_get_split_freq
|
|
|
|
* Assumes rig!=NULL, rx_freq!=NULL, tx_freq!=NULL
|
|
|
|
*/
|
2001-06-27 17:32:47 +00:00
|
|
|
int alinco_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
|
2001-06-03 17:39:59 +00:00
|
|
|
{
|
|
|
|
int retval;
|
|
|
|
char freqbuf[32];
|
|
|
|
|
|
|
|
retval = current_data_read(rig, freqbuf);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
/* extract TX freq first, as RX kills freqbuf[16] */
|
|
|
|
freqbuf[26] = '\0';
|
|
|
|
sscanf(freqbuf+16, "%Ld", tx_freq);
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2001-06-04 17:01:21 +00:00
|
|
|
* alinco_get_rit
|
2001-06-03 17:39:59 +00:00
|
|
|
* Assumes rig!=NULL, split!=NULL
|
|
|
|
*/
|
2001-06-04 17:01:21 +00:00
|
|
|
int alinco_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit)
|
2001-06-03 17:39:59 +00:00
|
|
|
{
|
2001-06-12 07:07:11 +00:00
|
|
|
int rit_len, retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
char ritbuf[32];
|
|
|
|
|
|
|
|
/* read in Hertz unit */
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction (rig, AL CMD_RIT "0" EOM,
|
|
|
|
strlen(AL CMD_RIT "0" EOM), ritbuf, &rit_len);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
if (rit_len > 5 || (ritbuf[0] != '+' && ritbuf[0] != '-')) {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_rit: wrong answer %s, "
|
|
|
|
"len=%d\n", ritbuf, rit_len);
|
|
|
|
return -RIG_ERJCTED;
|
|
|
|
}
|
|
|
|
ritbuf[rit_len] = '\0';
|
|
|
|
|
|
|
|
*rit = atoi(ritbuf);
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_set_func
|
|
|
|
* Assumes rig!=NULL
|
|
|
|
*/
|
|
|
|
int alinco_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
|
|
|
|
{
|
|
|
|
int cmd_len;
|
|
|
|
char cmdbuf[32];
|
|
|
|
|
|
|
|
/* Optimize:
|
|
|
|
* sort the switch cases with the most frequent first
|
|
|
|
*/
|
|
|
|
switch (func) {
|
|
|
|
case RIG_FUNC_TONE:
|
|
|
|
cmd_len = sprintf(cmdbuf, AL CMD_CTCSS "%02d" EOM, status?51:0);
|
|
|
|
|
|
|
|
return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL);
|
|
|
|
|
|
|
|
case RIG_FUNC_FAGC:
|
|
|
|
cmd_len = sprintf(cmdbuf, AL CMD_AGC "%02d" EOM, status?1:2);
|
|
|
|
|
|
|
|
return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL);
|
|
|
|
|
|
|
|
case RIG_FUNC_NB:
|
|
|
|
cmd_len = sprintf(cmdbuf, AL CMD_NB "%d" EOM, status?1:0);
|
|
|
|
|
|
|
|
return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL);
|
|
|
|
|
|
|
|
case RIG_FUNC_MON:
|
|
|
|
cmd_len = sprintf(cmdbuf, AL CMD_MON "%d" EOM, status?1:0);
|
|
|
|
|
|
|
|
return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL);
|
|
|
|
|
|
|
|
default:
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"Unsupported set_func %d\n", func);
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_get_func
|
|
|
|
* Assumes rig!=NULL, status!=NULL
|
|
|
|
*/
|
|
|
|
int alinco_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status)
|
|
|
|
{
|
|
|
|
int retval;
|
|
|
|
int settings;
|
|
|
|
char funcbuf[32];
|
|
|
|
|
|
|
|
/* Optimize:
|
|
|
|
* sort the switch cases with the most frequent first
|
|
|
|
*/
|
|
|
|
switch (func) {
|
|
|
|
case RIG_FUNC_TONE:
|
|
|
|
retval = current_data_read(rig, funcbuf);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
|
|
|
funcbuf[2] = '\0';
|
|
|
|
settings = strtol(funcbuf, (char **)NULL, 16);
|
|
|
|
*status = settings & 0x08 ? 1 : 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RIG_FUNC_FAGC:
|
|
|
|
retval = current_data_read(rig, funcbuf);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
|
|
|
funcbuf[2] = '\0';
|
|
|
|
settings = strtol(funcbuf, (char **)NULL, 16);
|
|
|
|
*status = settings & 0x01 ? 1 : 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RIG_FUNC_NB:
|
|
|
|
retval = current_data_read(rig, funcbuf);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
|
|
|
funcbuf[2] = '\0';
|
|
|
|
settings = strtol(funcbuf, (char **)NULL, 16);
|
|
|
|
*status = settings & 0x04 ? 1 : 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"Unsupported get_func %d\n", func);
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_set_level
|
|
|
|
* Assumes rig!=NULL
|
|
|
|
* FIXME: cannot support PREAMP and ATT both at same time (make sens though)
|
|
|
|
*/
|
|
|
|
int alinco_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
|
|
|
{
|
|
|
|
int cmd_len, lvl;
|
|
|
|
char cmdbuf[32];
|
|
|
|
|
|
|
|
/* Optimize:
|
|
|
|
* sort the switch cases with the most frequent first
|
|
|
|
*/
|
|
|
|
switch (level) {
|
|
|
|
case RIG_LEVEL_PREAMP:
|
|
|
|
switch (val.i) {
|
|
|
|
case 0: lvl = 0; break;
|
|
|
|
case 10: lvl = 1; break;
|
|
|
|
default: rig_debug(RIG_DEBUG_ERR, "Unsupported Preamp %d\n",
|
|
|
|
val.i);
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
}
|
|
|
|
cmd_len = sprintf(cmdbuf, AL CMD_RFGAIN "%02d" EOM, lvl);
|
|
|
|
|
|
|
|
return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL);
|
|
|
|
|
|
|
|
case RIG_LEVEL_ATT:
|
|
|
|
switch (val.i) {
|
|
|
|
case 0: lvl = 0; break;
|
|
|
|
case 10: lvl = 11; break;
|
|
|
|
case 20: lvl = 10; break;
|
|
|
|
default: rig_debug(RIG_DEBUG_ERR, "Unsupported Att %d\n",
|
|
|
|
val.i);
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
}
|
|
|
|
cmd_len = sprintf(cmdbuf, AL CMD_RFGAIN "%02d" EOM, lvl);
|
|
|
|
|
|
|
|
return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL);
|
|
|
|
|
|
|
|
case RIG_LEVEL_RFPOWER:
|
|
|
|
cmd_len = sprintf(cmdbuf, AL CMD_PWR "%1d" EOM, val.f<0.5 ? 1 : 0);
|
|
|
|
|
|
|
|
return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL);
|
|
|
|
|
|
|
|
default:
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"Unsupported get_level %d\n", level);
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_get_level
|
|
|
|
* Assumes rig!=NULL, val!=NULL
|
|
|
|
*/
|
|
|
|
int alinco_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
|
|
|
{
|
|
|
|
struct alinco_priv_caps *priv;
|
|
|
|
int retval, lvl_len;
|
|
|
|
char lvlbuf[32];
|
|
|
|
|
|
|
|
priv = (struct alinco_priv_caps*)rig->caps->priv;
|
|
|
|
|
|
|
|
/* Optimize:
|
|
|
|
* sort the switch cases with the most frequent first
|
|
|
|
*/
|
|
|
|
switch (level) {
|
|
|
|
case RIG_LEVEL_STRENGTH:
|
|
|
|
/* read A/D converted value */
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction (rig, AL CMD_SMETER "1" EOM,
|
2001-06-03 17:39:59 +00:00
|
|
|
strlen(AL CMD_SMETER "1" EOM), lvlbuf, &lvl_len);
|
2001-06-12 07:07:11 +00:00
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
if (lvl_len != 5) {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_level: wrong answer"
|
|
|
|
"len=%d\n", lvl_len);
|
|
|
|
return -RIG_ERJCTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
lvlbuf[5] = '\0';
|
|
|
|
val->i = rig_raw2val(atoi(lvlbuf+3), &priv->str_cal);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RIG_LEVEL_SQLSTAT:
|
|
|
|
return -RIG_ENIMPL; /* get_dcd ? */
|
|
|
|
|
|
|
|
case RIG_LEVEL_PREAMP:
|
|
|
|
retval = current_data_read(rig, lvlbuf);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
|
|
|
switch (lvlbuf[5]) {
|
|
|
|
case '2':
|
|
|
|
case '3':
|
|
|
|
case '0': val->i = 0; break;
|
|
|
|
case '1': val->i = 10; break;
|
|
|
|
default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Gain %c%c\n",
|
|
|
|
lvlbuf[4], lvlbuf[5]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RIG_LEVEL_ATT:
|
|
|
|
retval = current_data_read(rig, lvlbuf);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
|
|
|
switch (lvlbuf[5]) {
|
|
|
|
case '1':
|
|
|
|
case '0': val->i = 0; break;
|
|
|
|
case '2': val->i = 20; break;
|
|
|
|
case '3': val->i = 10; break;
|
|
|
|
default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Gain %c%c\n",
|
|
|
|
lvlbuf[4], lvlbuf[5]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RIG_LEVEL_RFPOWER:
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction (rig, AL CMD_RPOWER EOM,
|
2001-06-03 17:39:59 +00:00
|
|
|
strlen(AL CMD_RPOWER EOM), lvlbuf, &lvl_len);
|
2001-06-12 07:07:11 +00:00
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
if (lvl_len != 1) {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_level: wrong answer"
|
|
|
|
"len=%d\n", lvl_len);
|
|
|
|
return -RIG_ERJCTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* H or L */
|
|
|
|
val->f = lvlbuf[0] == 'H' ? 1.0 : 0.0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"Unsupported get_level %d\n", level);
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_set_ctcss
|
|
|
|
* Assumes rig!=NULL, rig->caps->ctcss_list != NULL
|
|
|
|
*/
|
|
|
|
int alinco_set_ctcss(RIG *rig, vfo_t vfo, tone_t tone)
|
|
|
|
{
|
|
|
|
const struct rig_caps *caps;
|
|
|
|
unsigned char tonebuf[16];
|
|
|
|
int tone_len;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
caps = rig->caps;
|
|
|
|
|
|
|
|
/* TODO: replace 200 by something like RIGTONEMAX */
|
|
|
|
for (i = 0; caps->ctcss_list[i] != 0 && i<200; i++) {
|
|
|
|
if (caps->ctcss_list[i] == tone)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (caps->ctcss_list[i] != tone)
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
|
|
|
|
tone_len = sprintf(tonebuf, AL CMD_CTCSS "%02d" EOM, i+1);
|
|
|
|
|
|
|
|
return alinco_transaction (rig, tonebuf, tone_len, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_get_ptt
|
|
|
|
* Assumes rig!=NULL, ptt!=NULL
|
|
|
|
*/
|
|
|
|
int alinco_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
|
|
|
|
{
|
|
|
|
char pttbuf[16];
|
2001-06-12 07:07:11 +00:00
|
|
|
int ptt_len, retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction (rig, AL CMD_PTT EOM,
|
|
|
|
strlen(AL CMD_PTT EOM), pttbuf, &ptt_len);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
if (ptt_len != 3 || ptt_len != 4) {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_ptt: wrong answer %s, "
|
|
|
|
"len=%d\n", pttbuf, ptt_len);
|
|
|
|
return -RIG_ERJCTED;
|
|
|
|
}
|
|
|
|
pttbuf[ptt_len] = '\0';
|
|
|
|
|
|
|
|
if (!strcmp(pttbuf, "SEND"))
|
|
|
|
*ptt = RIG_PTT_OFF;
|
|
|
|
else if (!strcmp(pttbuf, "REV"))
|
|
|
|
*ptt = RIG_PTT_ON;
|
|
|
|
else {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_ptt: unknown PTT %s\n",
|
|
|
|
pttbuf);
|
|
|
|
return -RIG_EPROTO;
|
|
|
|
}
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_get_dcd
|
|
|
|
* Assumes rig!=NULL, dcd!=NULL
|
|
|
|
*/
|
|
|
|
int alinco_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd)
|
|
|
|
{
|
|
|
|
char dcdbuf[16];
|
2001-06-12 07:07:11 +00:00
|
|
|
int dcd_len, retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction (rig, AL CMD_SQL EOM,
|
|
|
|
strlen(AL CMD_SQL EOM), dcdbuf, &dcd_len);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
if (dcd_len != 4 || dcd_len != 5) {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_dcd: wrong answer %s, "
|
|
|
|
"len=%d\n", dcdbuf, dcd_len);
|
|
|
|
return -RIG_ERJCTED;
|
|
|
|
}
|
|
|
|
dcdbuf[dcd_len] = '\0';
|
|
|
|
|
|
|
|
if (!strcmp(dcdbuf, "OPEN"))
|
|
|
|
*dcd = RIG_DCD_ON;
|
|
|
|
else if (!strcmp(dcdbuf, "CLOSE"))
|
|
|
|
*dcd = RIG_DCD_OFF;
|
|
|
|
else {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_dcd: unknown SQL %s\n",
|
|
|
|
dcdbuf);
|
|
|
|
return -RIG_EPROTO;
|
|
|
|
}
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_set_mem
|
|
|
|
* Assumes rig!=NULL
|
|
|
|
* FIXME: check we're in memory mode first
|
|
|
|
*/
|
|
|
|
int alinco_set_mem(RIG *rig, vfo_t vfo, int ch)
|
|
|
|
{
|
|
|
|
char cmdbuf[16];
|
|
|
|
int cmd_len;
|
|
|
|
|
|
|
|
if (ch < 0 || ch > 99)
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
|
|
|
|
cmd_len = sprintf(cmdbuf, AL CMD_MCALL "%02d" EOM, ch);
|
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
return alinco_transaction (rig, cmdbuf, cmd_len, NULL, NULL);
|
2001-06-03 17:39:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* alinco_get_mem
|
|
|
|
* Assumes rig!=NULL, !vfo
|
|
|
|
*/
|
|
|
|
int alinco_get_mem(RIG *rig, vfo_t vfo, int *ch)
|
|
|
|
{
|
|
|
|
char membuf[16];
|
2001-06-12 07:07:11 +00:00
|
|
|
int mem_len, retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
2001-06-12 07:07:11 +00:00
|
|
|
retval = alinco_transaction (rig, AL CMD_RMEM EOM,
|
|
|
|
strlen(AL CMD_RMEM EOM), membuf, &mem_len);
|
|
|
|
if (retval != RIG_OK)
|
|
|
|
return retval;
|
2001-06-03 17:39:59 +00:00
|
|
|
|
|
|
|
if (mem_len != 2) {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_mem: wrong answer %s, "
|
|
|
|
"len=%d\n", membuf, mem_len);
|
|
|
|
return -RIG_ERJCTED;
|
|
|
|
}
|
|
|
|
membuf[mem_len] = '\0';
|
|
|
|
|
|
|
|
*ch = atoi(membuf);
|
|
|
|
if (*ch < 0 || *ch > 99) {
|
|
|
|
rig_debug(RIG_DEBUG_ERR,"alinco_get_mem: unknown mem %s\n",
|
|
|
|
membuf);
|
|
|
|
return -RIG_EPROTO;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* init_alinco is called by rig_backend_load
|
|
|
|
*/
|
|
|
|
int init_alinco(void *be_handle)
|
|
|
|
{
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "alinco: _init called\n");
|
|
|
|
|
|
|
|
rig_register(&dx77_caps);
|
|
|
|
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|