kopia lustrzana https://github.com/Hamlib/Hamlib
1956 wiersze
46 KiB
C
1956 wiersze
46 KiB
C
/*
|
|
* Hamlib AOR backend - AR7030 Plus description
|
|
* Copyright (c) 2000-2010 by Stephane Fillod & Fritz Melchert
|
|
* Copyright (c) 2009-2010 by Larry Gadallah (VE6VQ)
|
|
*
|
|
*
|
|
* 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
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Version 2009.11.21 Larry Gadallah (VE6VQ)
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "hamlib/rig.h"
|
|
#include "ar7030p.h"
|
|
#include "serial.h"
|
|
#include "idx_builtin.h"
|
|
|
|
#define AR7030P_MODES ( RIG_MODE_AM | \
|
|
RIG_MODE_SSB | \
|
|
RIG_MODE_CW | \
|
|
RIG_MODE_RTTY | \
|
|
RIG_MODE_FM | \
|
|
RIG_MODE_AMS )
|
|
|
|
#define AR7030P_FUNC ( RIG_FUNC_FAGC | \
|
|
RIG_FUNC_NB | \
|
|
RIG_FUNC_ANF | \
|
|
RIG_FUNC_AIP | \
|
|
RIG_FUNC_MN | \
|
|
RIG_FUNC_RF | \
|
|
RIG_FUNC_LOCK | \
|
|
RIG_FUNC_MUTE | \
|
|
RIG_FUNC_SQL )
|
|
|
|
#define AR7030P_LEVEL ( RIG_LEVEL_PREAMP | \
|
|
RIG_LEVEL_ATT | \
|
|
RIG_LEVEL_AF | \
|
|
RIG_LEVEL_RF | \
|
|
RIG_LEVEL_SQL | \
|
|
RIG_LEVEL_PBT_IN | \
|
|
RIG_LEVEL_CWPITCH | \
|
|
RIG_LEVEL_NOTCHF | \
|
|
RIG_LEVEL_AGC | \
|
|
RIG_LEVEL_RAWSTR | \
|
|
RIG_LEVEL_STRENGTH )
|
|
|
|
#define AR7030P_PARM ( RIG_PARM_APO | \
|
|
RIG_PARM_TIME | \
|
|
RIG_PARM_BAT )
|
|
|
|
#define AR7030P_VFO_OPS ( RIG_OP_CPY | \
|
|
RIG_OP_XCHG | \
|
|
RIG_OP_TOGGLE )
|
|
|
|
#define AR7030P_VFO ( RIG_VFO_A | \
|
|
RIG_VFO_B)
|
|
|
|
#define AR7030P_STR_CAL { 8, { \
|
|
{ 10, -113 }, \
|
|
{ 10, -103 }, \
|
|
{ 10, -93 }, \
|
|
{ 10, -83 }, \
|
|
{ 10, -73 }, \
|
|
{ 10, -63 }, \
|
|
{ 20, -43 }, \
|
|
{ 20, -23 }, \
|
|
} }
|
|
|
|
/* Channel capabilities
|
|
- Frequency
|
|
- Mode
|
|
- Width
|
|
- Scan lockout
|
|
- PBT
|
|
- Squelch
|
|
- ID
|
|
*/
|
|
#define AR7030P_MEM_CAP { \
|
|
.freq = 1, \
|
|
.mode = 1, \
|
|
.width = 1, \
|
|
.funcs = RIG_FUNC_NONE, \
|
|
.levels = RIG_LEVEL_SQL | RIG_LEVEL_PBT_IN, \
|
|
.flags = 1, \
|
|
.channel_desc = 1 \
|
|
}
|
|
|
|
struct ar7030p_priv_caps
|
|
{
|
|
int max_freq_len;
|
|
int info_len;
|
|
int mem_len;
|
|
int pbs_info_len;
|
|
int pbs_len;
|
|
int chan_num;
|
|
};
|
|
|
|
static const struct ar7030p_priv_caps ar7030p_priv_caps =
|
|
{
|
|
.max_freq_len = 3,
|
|
.info_len = 14,
|
|
.mem_len = 17,
|
|
.pbs_info_len = 1,
|
|
.pbs_len = 1,
|
|
.chan_num = 0,
|
|
};
|
|
|
|
#define NB_CHAN 400 /* see caps->chan_list */
|
|
|
|
struct ar7030p_priv_data
|
|
{
|
|
vfo_t curr_vfo;
|
|
vfo_t last_vfo; /* VFO A or VFO B, when in MEM mode */
|
|
|
|
powerstat_t powerstat;
|
|
int bank;
|
|
value_t parms[ RIG_SETTING_MAX ];
|
|
|
|
channel_t *curr; /* points to vfo_a, vfo_b or mem[] */
|
|
|
|
channel_t vfo_a;
|
|
channel_t vfo_b;
|
|
channel_t mem[ NB_CHAN ];
|
|
|
|
struct ext_list *ext_parms;
|
|
};
|
|
|
|
static const struct confparams ar7030p_ext_levels[] =
|
|
{
|
|
{
|
|
TOK_EL_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example",
|
|
NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } }
|
|
},
|
|
|
|
{
|
|
TOK_EL_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example",
|
|
NULL, RIG_CONF_CHECKBUTTON
|
|
},
|
|
|
|
{
|
|
TOK_EL_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example",
|
|
NULL, RIG_CONF_BUTTON
|
|
},
|
|
|
|
{ RIG_CONF_END, NULL, }
|
|
};
|
|
|
|
static const struct confparams ar7030p_ext_parms[] =
|
|
{
|
|
{
|
|
TOK_EP_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example",
|
|
NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } }
|
|
},
|
|
|
|
{ RIG_CONF_END, NULL, }
|
|
};
|
|
|
|
/* TODO - move this somewhere where it belongs */
|
|
static unsigned int filterTab[ 6 + 1 ] = { 0 };
|
|
|
|
|
|
static void init_chan(RIG *rig, vfo_t vfo, channel_t *chan)
|
|
{
|
|
assert(NULL != rig);
|
|
assert(NULL != chan);
|
|
|
|
chan->channel_num = 0;
|
|
chan->vfo = vfo;
|
|
|
|
strcpy(chan->channel_desc, rig_strvfo(vfo));
|
|
|
|
chan->freq = MHz(10);
|
|
chan->mode = RIG_MODE_AM;
|
|
chan->width = rig_passband_normal(rig, RIG_MODE_AM);
|
|
|
|
chan->tuning_step = 110;
|
|
|
|
chan->funcs = (setting_t) 0;
|
|
|
|
memset(chan->levels, 0, RIG_SETTING_MAX * sizeof(value_t));
|
|
}
|
|
|
|
static struct ext_list *alloc_init_ext(const struct confparams *cfp)
|
|
{
|
|
struct ext_list *elp;
|
|
int i, nb_ext;
|
|
|
|
assert(NULL != cfp);
|
|
|
|
for (nb_ext = 0; !RIG_IS_EXT_END(cfp[nb_ext]); nb_ext++)
|
|
{
|
|
;
|
|
}
|
|
|
|
elp = calloc((nb_ext + 1), sizeof(struct ext_list));
|
|
|
|
if (!elp)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
for (i = 0; !RIG_IS_EXT_END(cfp[i]); i++)
|
|
{
|
|
elp[i].token = cfp[i].token;
|
|
/* value reset already by calloc */
|
|
}
|
|
|
|
/* last token in array is set to 0 by calloc */
|
|
return elp;
|
|
}
|
|
|
|
#if 0 /* unused; re-enabled as needed. */
|
|
static struct ext_list *find_ext(struct ext_list *elp, token_t token)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; elp[ i ].token != 0; i++)
|
|
{
|
|
if (elp[ i ].token == token)
|
|
{
|
|
return &(elp[ i ]);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#endif /* unused */
|
|
|
|
static int ar7030p_init(RIG *rig)
|
|
{
|
|
struct ar7030p_priv_data *priv;
|
|
int rc = RIG_OK;
|
|
|
|
assert(NULL != rig);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
|
|
|
priv = (struct ar7030p_priv_data *)
|
|
malloc(sizeof(struct ar7030p_priv_data));
|
|
|
|
if (!priv)
|
|
{
|
|
rc = -RIG_ENOMEM;
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
|
|
rig->state.priv = (void *) priv;
|
|
|
|
rig->state.rigport.type.rig = RIG_PORT_SERIAL;
|
|
|
|
priv->powerstat = RIG_POWER_ON;
|
|
priv->bank = 0;
|
|
|
|
memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t));
|
|
|
|
memset(priv->mem, 0, sizeof(priv->mem));
|
|
|
|
for (i = 0; i < NB_CHAN; i++)
|
|
{
|
|
priv->mem[ i ].channel_num = i;
|
|
priv->mem[ i ].vfo = RIG_VFO_MEM;
|
|
|
|
priv->mem[ i ].ext_levels = alloc_init_ext(ar7030p_ext_levels);
|
|
|
|
if (!priv->mem[ i ].ext_levels)
|
|
{
|
|
rc = -RIG_ENOMEM;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
priv->vfo_a.ext_levels = alloc_init_ext(ar7030p_ext_levels);
|
|
|
|
if (!priv->vfo_a.ext_levels)
|
|
{
|
|
return -RIG_ENOMEM;
|
|
}
|
|
else
|
|
{
|
|
priv->vfo_b.ext_levels = alloc_init_ext(ar7030p_ext_levels);
|
|
}
|
|
|
|
if (!priv->vfo_b.ext_levels)
|
|
{
|
|
return -RIG_ENOMEM;
|
|
}
|
|
|
|
priv->ext_parms = alloc_init_ext(ar7030p_ext_parms);
|
|
|
|
if (!priv->ext_parms)
|
|
{
|
|
return -RIG_ENOMEM;
|
|
}
|
|
|
|
init_chan(rig, RIG_VFO_A, &priv->vfo_a);
|
|
init_chan(rig, RIG_VFO_B, &priv->vfo_b);
|
|
|
|
priv->curr = &priv->vfo_a;
|
|
priv->curr_vfo = priv->last_vfo = RIG_VFO_A;
|
|
}
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_cleanup(RIG *rig)
|
|
{
|
|
struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) rig->state.priv;
|
|
int rc = RIG_OK;
|
|
int i;
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
|
|
|
for (i = 0; i < NB_CHAN; i++)
|
|
{
|
|
free(priv->mem[ i ].ext_levels);
|
|
}
|
|
|
|
free(priv->vfo_a.ext_levels);
|
|
free(priv->vfo_b.ext_levels);
|
|
|
|
free(priv->ext_parms);
|
|
|
|
if (NULL != rig->state.priv)
|
|
{
|
|
free(rig->state.priv);
|
|
}
|
|
|
|
rig->state.priv = NULL;
|
|
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* /brief Open I/O to receiver
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
*
|
|
* /return 0 on success, < 0 on failure
|
|
*/
|
|
static int ar7030p_open(RIG *rig)
|
|
{
|
|
int rc = RIG_OK;
|
|
unsigned char v;
|
|
|
|
assert(NULL != rig);
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
int i;
|
|
|
|
/* Load calibration table */
|
|
rig->state.str_cal.size = rig->caps->str_cal.size;
|
|
|
|
for (i = 0; i < rig->state.str_cal.size; i++)
|
|
{
|
|
rc = readByte(rig, EEPROM1, SM_CAL + i, &v);
|
|
|
|
if (RIG_OK != rc)
|
|
{
|
|
break;
|
|
}
|
|
|
|
rig->state.str_cal.table[ i ].val = rig->caps->str_cal.table[ i ].val;
|
|
rig->state.str_cal.table[ i ].raw = (int) v;
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: index %d, val %d, raw %d\n",
|
|
__func__, i, rig->state.str_cal.table[ i ].val,
|
|
rig->state.str_cal.table[ i ].raw);
|
|
}
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Load filter BW table */
|
|
for (i = 1; i <= 6; i++)
|
|
{
|
|
rc = getFilterBW(rig, i);
|
|
|
|
if (rc < 0)
|
|
{
|
|
rig_debug(RIG_DEBUG_ERR, "%s: err in getFilterBW: %s\n", __func__,
|
|
rigerror(rc));
|
|
return rc;
|
|
}
|
|
else
|
|
{
|
|
filterTab[i] = (unsigned int) rc;
|
|
}
|
|
}
|
|
}
|
|
|
|
rc = lockRx(rig, LOCK_0);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: \n", __func__);
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* /brief Close I/O to receiver
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
*
|
|
* /return 0 on success, < 0 on failure
|
|
*/
|
|
static int ar7030p_close(RIG *rig)
|
|
{
|
|
assert(NULL != rig);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: \n", __func__);
|
|
|
|
return (RIG_OK);
|
|
}
|
|
|
|
static const char *ar7030p_get_info(RIG *rig)
|
|
{
|
|
static char version[10] = "";
|
|
unsigned int i;
|
|
char *p = &(version[ 0 ]);
|
|
|
|
assert(NULL != rig);
|
|
|
|
for (i = 0; i < pageSize(ROM); i++)
|
|
{
|
|
if (RIG_OK != readByte(rig, ROM, i, (unsigned char *) p++))
|
|
{
|
|
p = NULL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (NULL != p)
|
|
{
|
|
*p++ = '\0';
|
|
p = &(version[ 0 ]);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: ident - %s\n", __func__, version);
|
|
}
|
|
|
|
return (p);
|
|
}
|
|
|
|
/*
|
|
* /brief Set receiver frequency
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param vfo VFO to operate on
|
|
* /param freq Frequency to set
|
|
*
|
|
*/
|
|
static int ar7030p_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
|
{
|
|
int rc = RIG_OK;
|
|
|
|
assert(NULL != rig);
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
const struct rig_caps *caps = rig->caps;
|
|
|
|
if ((caps->rx_range_list1[ 0 ].endf > freq) &&
|
|
(caps->rx_range_list1[ 0 ].startf < freq))
|
|
{
|
|
switch (vfo)
|
|
{
|
|
case RIG_VFO_CURR:
|
|
case RIG_VFO_A:
|
|
rc = write3Bytes(rig, WORKING, FREQU, hzToDDS(freq));
|
|
break;
|
|
|
|
case RIG_VFO_B:
|
|
rc = write3Bytes(rig, WORKING, FREQU_B, hzToDDS(freq));
|
|
break;
|
|
|
|
default:
|
|
rc = -RIG_EINVAL;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = -RIG_EINVAL;
|
|
}
|
|
|
|
// this RIG_OK check added to clear cppcheck warnings
|
|
// not sure if it's needed but seem like RIG_OK should be expected
|
|
// if this debug prints out when things are working need to reexamine
|
|
if (rc != RIG_OK)
|
|
{
|
|
rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc));
|
|
}
|
|
|
|
rc = execRoutine(rig, SET_ALL);
|
|
|
|
if (rc == RIG_OK) { rc = lockRx(rig, LOCK_0); }
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* /brief Get receiver frequency
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param vfo VFO to operate on
|
|
* /param freq Pointer to hold frequency value (in Hz)
|
|
*
|
|
*/
|
|
static int ar7030p_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
|
{
|
|
int rc = RIG_OK;
|
|
unsigned int x;
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
switch (vfo)
|
|
{
|
|
case RIG_VFO_CURR:
|
|
case RIG_VFO_A:
|
|
rc = read3Bytes(rig, WORKING, FREQU, &x);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
*freq = ddsToHz(x);
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_VFO_B:
|
|
rc = read3Bytes(rig, WORKING, FREQU_B, &x);
|
|
{
|
|
*freq = ddsToHz(x);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
rc = -RIG_EINVAL;
|
|
break;
|
|
}
|
|
|
|
// this RIG_OK check added to clear cppcheck warnings
|
|
// not sure if it's needed but seem like RIG_OK should be expected
|
|
// if this debug prints out when things are working need to reexamine
|
|
if (rc != RIG_OK)
|
|
{
|
|
rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc));
|
|
}
|
|
|
|
rc = lockRx(rig, LOCK_0);
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* /brief Set receiver mode
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param vfo VFO to operate on
|
|
* /param mode Mode to set
|
|
* /param width Bandwidth to set
|
|
*
|
|
*/
|
|
static int ar7030p_set_mode(RIG *rig, vfo_t vfo, rmode_t mode,
|
|
pbwidth_t width)
|
|
{
|
|
int rc = RIG_OK;
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* TODO - deal with selected VFO */
|
|
unsigned char ar_mode = modeToNative(mode);
|
|
|
|
rc = writeByte(rig, WORKING, MODE, ar_mode);
|
|
|
|
if (RIG_OK == rc && width != RIG_PASSBAND_NOCHANGE)
|
|
{
|
|
int i;
|
|
|
|
/* TODO - get filter BWs at startup */
|
|
unsigned char ar_filter = (unsigned char) 6;
|
|
|
|
for (i = 1; i <= 6; i++)
|
|
{
|
|
if (width <= filterTab[ i ])
|
|
{
|
|
if (filterTab[ i ] < filterTab[(int) ar_filter ])
|
|
{
|
|
ar_filter = (unsigned char) i;
|
|
}
|
|
}
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: width %d ar_filter %d filterTab[%d] %u\n",
|
|
__func__, (int)width, ar_filter, i, filterTab[i]);
|
|
}
|
|
|
|
rc = writeByte(rig, WORKING, FILTER, ar_filter);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
rc = execRoutine(rig, SET_ALL);
|
|
}
|
|
}
|
|
|
|
// this RIG_OK check added to clear cppcheck warnings
|
|
// not sure if it's needed but seem like RIG_OK should be expected
|
|
// if this debug prints out when things are working need to reexamine
|
|
if (rc != RIG_OK)
|
|
{
|
|
rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc));
|
|
}
|
|
|
|
rc = lockRx(rig, LOCK_0);
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* /brief Get receiver mode and bandwidth
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param vfo VFO to operate on
|
|
* /param mode Pointer to value to hold mode
|
|
* /param width Pointer to value to hold bandwidth
|
|
*
|
|
*/
|
|
static int ar7030p_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode,
|
|
pbwidth_t *width)
|
|
{
|
|
int rc = RIG_OK;
|
|
unsigned char bcd_bw;
|
|
unsigned char m;
|
|
|
|
assert(NULL != rig);
|
|
assert(NULL != mode);
|
|
assert(NULL != width);
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* TODO - deal with selected VFO */
|
|
rc = readByte(rig, WORKING, MODE, &m);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
*mode = modeToHamlib(m);
|
|
rc = readByte(rig, WORKING, FLTBW, &bcd_bw);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
*width = (pbwidth_t)((int) bcd2Int(bcd_bw) * 100);
|
|
}
|
|
}
|
|
|
|
rc = lockRx(rig, LOCK_0);
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* /brief Get memory channel parameters
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param chan Channel number (0-399)
|
|
* /param freq Pointer to frequency value
|
|
* /param mode Pointer to mode value (1-7)
|
|
* /param filt Pointer to filter value (1-6)
|
|
* /param pbs Pointer to passband tuning value
|
|
* /param sql Pointer to squelch value (0-255)
|
|
* /param id Pointer to channel ident string (14 chars)
|
|
*
|
|
*/
|
|
#if 0 /* unused; re-enabled as needed. */
|
|
static void ar7030p_get_memory(RIG *rig, const unsigned int chan,
|
|
double *const freq, unsigned char *const mode,
|
|
unsigned char *const filt, unsigned char *const pbs,
|
|
unsigned char *const sql, char *const id)
|
|
{
|
|
int rc = RIG_OK;
|
|
unsigned char v;
|
|
unsigned int f;
|
|
unsigned char *p = (unsigned char *) id;
|
|
int i;
|
|
|
|
assert(NULL != rig);
|
|
assert(NULL != freq);
|
|
assert(NULL != mode);
|
|
assert(NULL != filt);
|
|
assert(NULL != pbs);
|
|
assert(NULL != sql);
|
|
assert(NULL != id);
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Squelch values */
|
|
if (100 > chan)
|
|
{
|
|
rc = readByte(rig, BBRAM, (MEM_SQ + chan), &v); /* mem_sq */
|
|
}
|
|
else if (176 > chan)
|
|
{
|
|
rc = readByte(rig, EEPROM2, (MEX_SQ + (chan * 16)), &v); /* mex_sq */
|
|
}
|
|
else
|
|
{
|
|
rc = readByte(rig, EEPROM3, (MEY_SQ + ((chan - 176) * 16)), &v); /* mey_sq */
|
|
}
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
*sql = v;
|
|
}
|
|
|
|
/* Frequency, mode and filter values */
|
|
if (100 > chan)
|
|
{
|
|
rc = read3Bytes(rig, EEPROM2, (MEM_FR + (chan * 4)), &f); /* mem_fr */
|
|
rc = readByte(rig, EEPROM2, (MEM_MD + (chan * 4)), &v); /* mem_md */
|
|
}
|
|
else
|
|
{
|
|
rc = read3Bytes(rig, EEPROM3, (MEX_FR + ((chan - 100) * 4)),
|
|
&f); /* mex_fr */
|
|
rc = readByte(rig, EEPROM3, (MEX_MD + ((chan - 100) * 4)),
|
|
&v); /* mex_md */
|
|
}
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
*freq = ddsToHz(f);
|
|
*mode = (v & 0x07);
|
|
*filt = ((v & 0x70) >> 4);
|
|
/* lockout = ( ( v & 0x80 ) >> 7 ); */
|
|
}
|
|
|
|
/* PBT values */
|
|
if (100 > chan)
|
|
{
|
|
rc = readByte(rig, EEPROM1, (MEM_PB + chan), &v); /* mem_pb */
|
|
}
|
|
else if (176 > chan)
|
|
{
|
|
rc = readByte(rig, EEPROM2, (MEX_PB + (chan * 16)), &v); /* mex_pb */
|
|
}
|
|
else
|
|
{
|
|
rc = readByte(rig, EEPROM3, (MEY_PB + ((chan - 176) * 16)), &v); /* mey_pb */
|
|
}
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
*pbs = v;
|
|
}
|
|
|
|
/* Memory ID values */
|
|
for (i = 0; i < 14; i++)
|
|
{
|
|
if (176 > chan)
|
|
{
|
|
rc = readByte(rig, EEPROM2, (MEX_ID + (chan * 16)), p++); /* mex_id */
|
|
}
|
|
else
|
|
{
|
|
rc = readByte(rig, EEPROM3, (MEY_ID + ((chan - 176) * 16)), p++); /* mey_id */
|
|
}
|
|
|
|
if (RIG_OK != rc)
|
|
{
|
|
p = (unsigned char *) id;
|
|
break;
|
|
}
|
|
}
|
|
|
|
*p++ = '\0';
|
|
|
|
rc = lockRx(rig, LOCK_0);
|
|
}
|
|
|
|
}
|
|
#endif /* unused */
|
|
|
|
/*
|
|
* /brief Set receiver levels
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param vfo VFO to operate on
|
|
* /param level Level to set
|
|
* /param val Value to set level to
|
|
*
|
|
* /return RIG_OK on success
|
|
*/
|
|
static int ar7030p_set_level(RIG *rig, vfo_t vfo, setting_t level,
|
|
value_t val)
|
|
{
|
|
int rc = RIG_OK;
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* TODO - deal with selected VFO */
|
|
switch (level)
|
|
{
|
|
unsigned char v;
|
|
|
|
case RIG_LEVEL_PREAMP:
|
|
|
|
/* Scale parameter */
|
|
if (10 <= val.i)
|
|
{
|
|
v = (unsigned char) 0;
|
|
}
|
|
else
|
|
{
|
|
v = (unsigned char) 1;
|
|
}
|
|
|
|
rc = writeByte(rig, WORKING, RFGAIN, v); /* rfgain */
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, val.i, v);
|
|
|
|
if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_ATT:
|
|
|
|
/* Scale parameter */
|
|
if (10 > val.i)
|
|
{
|
|
v = (unsigned char) 1;
|
|
}
|
|
else if (20 > val.i)
|
|
{
|
|
v = (unsigned char) 2;
|
|
}
|
|
else if (40 > val.i)
|
|
{
|
|
v = (unsigned char) 3;
|
|
}
|
|
else if (80 > val.i)
|
|
{
|
|
v = (unsigned char) 4;
|
|
}
|
|
else
|
|
{
|
|
v = (unsigned char) 5;
|
|
}
|
|
|
|
rc = writeByte(rig, WORKING, RFGAIN, v); /* rfgain */
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, val.i, v);
|
|
|
|
if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_AF:
|
|
/* Scale parameter */
|
|
v = (unsigned char)((val.f * (VOL_MAX - VOL_MIN)) + VOL_MIN);
|
|
v = (v & 0x3f);
|
|
|
|
rc = writeByte(rig, WORKING, AF_VOL, v); /* af_vol */
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: af_vol %f (%d)\n", __func__, val.f, v);
|
|
|
|
v = ((v >> 1) & 0x1f); /* half value for L/R volume */
|
|
|
|
if (rc == RIG_OK) { rc = writeByte(rig, WORKING, AF_VLL, v); } /* af_vll */
|
|
|
|
if (rc == RIG_OK) { rc = writeByte(rig, WORKING, AF_VLR, v); } /* af_vlr */
|
|
|
|
if (rc == RIG_OK) { rc = execRoutine(rig, SET_AUDIO); }
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_RF:
|
|
/* Scale parameter, values 0 (99%) to 130 (3%) */
|
|
v = (unsigned char)(134U - ((unsigned int)(val.f * 135.0)));
|
|
|
|
rc = writeByte(rig, WORKING, IFGAIN, v); /* ifgain */
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: ifgain %f (%d)\n", __func__, val.f, v);
|
|
|
|
if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_SQL:
|
|
/* Scale parameter */
|
|
v = (unsigned char)(val.f * 255.0);
|
|
|
|
rc = writeByte(rig, WORKING, SQLVAL, v); /* sqlval */
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: sqlval %f (%d)\n", __func__, val.f, v);
|
|
|
|
if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_PBT_IN:
|
|
/* Scale parameter */
|
|
v = (unsigned char)(val.f / (HZ_PER_STEP * 12.5));
|
|
|
|
rc = writeByte(rig, WORKING, PBSVAL, v); /* pbsval */
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: pbsval %f (%d)\n", __func__, val.f, v);
|
|
|
|
if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_CWPITCH:
|
|
/* Scale parameter */
|
|
v = (unsigned char)(val.f / (HZ_PER_STEP * 12.5));
|
|
|
|
rc = writeByte(rig, WORKING, BFOVAL, v); /* bfoval */
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: bfoval %f (%d)\n", __func__, val.f, v);
|
|
|
|
if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_NOTCHF:
|
|
rc = -RIG_ENIMPL;
|
|
break;
|
|
|
|
case RIG_LEVEL_AGC:
|
|
/* Scale parameter */
|
|
v = agcToNative(val.i);
|
|
rc = writeByte(rig, WORKING, AGCSPD, v); /* agcspd */
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: agcspd %d (%d)\n", __func__, val.i, v);
|
|
|
|
if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); }
|
|
|
|
break;
|
|
|
|
default:
|
|
rc = -RIG_EINVAL;
|
|
break;
|
|
}
|
|
|
|
// this RIG_OK check added to clear cppcheck warnings
|
|
// not sure if it's needed but seem like RIG_OK should be expected
|
|
// if this debug prints out when things are working need to reexamine
|
|
if (rc != RIG_OK)
|
|
{
|
|
rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc));
|
|
}
|
|
|
|
rc = lockRx(rig, LOCK_0);
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
|
|
/*
|
|
* /brief Get receiver levels
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param vfo VFO to operate on
|
|
* /param level Level to get
|
|
* /param val Pointer to value to get
|
|
*
|
|
* /return RIG_OK on success
|
|
*/
|
|
static int ar7030p_get_level(RIG *rig, vfo_t vfo, setting_t level,
|
|
value_t *val)
|
|
{
|
|
int rc = RIG_OK;
|
|
unsigned char v;
|
|
unsigned short s = 0;
|
|
int i;
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* TODO - deal with selected VFO */
|
|
switch (level)
|
|
{
|
|
case RIG_LEVEL_PREAMP:
|
|
rc = readByte(rig, WORKING, RFGAIN, &v); /* rfgain */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Scale parameter */
|
|
if (0 == v)
|
|
{
|
|
val->i = 10;
|
|
}
|
|
else
|
|
{
|
|
val->i = 0;
|
|
}
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n",
|
|
__func__, v, val->i);
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_ATT:
|
|
rc = readByte(rig, WORKING, RFGAIN, &v); /* rfgain */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Scale parameter */
|
|
switch (v)
|
|
{
|
|
case 2:
|
|
val->i = 10;
|
|
break;
|
|
|
|
case 3:
|
|
val->i = 20;
|
|
break;
|
|
|
|
case 4:
|
|
val->i = 40;
|
|
break;
|
|
|
|
default:
|
|
case 0:
|
|
case 1:
|
|
val->i = 0;
|
|
};
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n",
|
|
__func__, v, val->i);
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_AF:
|
|
rc = readByte(rig, WORKING, AF_VOL, &v); /* af_vol */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Scale parameter */
|
|
v = (v & 0x3f);
|
|
val->f = (((float) v - VOL_MIN) / (VOL_MAX - VOL_MIN));
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: af_vol %d (%f)\n",
|
|
__func__, v, val->f);
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_RF:
|
|
rc = readByte(rig, WORKING, IFGAIN, &v); /* ifgain */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Scale parameter, values 0 (99%) to 130 (3%) */
|
|
val->f = ((float)(134 - v) / 135.0);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: ifgain %d (%f)\n",
|
|
__func__, v, val->f);
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_SQL:
|
|
rc = readByte(rig, WORKING, SQLVAL, &v); /* sqlval */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Scale parameter */
|
|
val->f = ((float)(v) / 255.0);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: sqlval %d (%f)\n",
|
|
__func__, v, val->f);
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_PBT_IN:
|
|
rc = readByte(rig, WORKING, PBSVAL, &v); /* pbsval */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Scale parameter */
|
|
if (127 < v)
|
|
{
|
|
v = v | 0xffffff00;
|
|
}
|
|
|
|
val->f = ((float)(v) * HZ_PER_STEP * 12.5);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: pbsval %d (%f)\n",
|
|
__func__, v, val->f);
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_CWPITCH:
|
|
rc = readByte(rig, WORKING, BFOVAL, &v); /* bfoval */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Scale parameter */
|
|
if (127 < v)
|
|
{
|
|
v = v | 0xffffff00;
|
|
}
|
|
|
|
val->f = ((float)(v) * HZ_PER_STEP * 12.5);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: bfoval %d (%f)\n",
|
|
__func__, v, val->f);
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_NOTCHF:
|
|
rc = readShort(rig, WORKING, NCHFR, &s); /* nchfr */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
unsigned int x = (unsigned int) s;
|
|
|
|
/* Scale parameter */
|
|
val->i = (int)((float)(x) / NOTCH_STEP_HZ);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: nchfr %u (%d)\n",
|
|
__func__, x, val->i);
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_AGC:
|
|
rc = readByte(rig, WORKING, AGCSPD, &v); /* agcspd */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Scale parameter */
|
|
val->i = agcToHamlib(v);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: agcspd %d (%d)\n",
|
|
__func__, v, val->i);
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_RAWSTR:
|
|
rc = readSignal(rig, &v);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
val->i = (int) v;
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_LEVEL_STRENGTH:
|
|
rc = readSignal(rig, &v);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
rc = getCalLevel(rig, v, &i);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
val->i = i;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
rc = -RIG_EINVAL;
|
|
}
|
|
|
|
if (RIG_OK == rc) { rc = lockRx(rig, LOCK_0); }
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_set_vfo(RIG *rig, vfo_t vfo)
|
|
{
|
|
int rc = RIG_OK;
|
|
struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) rig->state.priv;
|
|
|
|
switch (vfo)
|
|
{
|
|
case RIG_VFO_B:
|
|
if (RIG_VFO_B != priv->curr_vfo)
|
|
{
|
|
rc = sendIRCode(rig, IR_VFO);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
priv->curr_vfo = RIG_VFO_B;
|
|
priv->last_vfo = RIG_VFO_A;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case RIG_VFO_A:
|
|
case RIG_VFO_CURR:
|
|
if (RIG_VFO_A != priv->curr_vfo)
|
|
{
|
|
rc = sendIRCode(rig, IR_VFO);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
priv->curr_vfo = RIG_VFO_A;
|
|
priv->last_vfo = RIG_VFO_B;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
rc = -RIG_EINVAL;
|
|
break;
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_get_vfo(RIG *rig, vfo_t *vfo)
|
|
{
|
|
int rc = RIG_OK;
|
|
struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) rig->state.priv;
|
|
|
|
assert(NULL != vfo);
|
|
|
|
*vfo = priv->curr_vfo;
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_set_parm(RIG *rig, setting_t parm, value_t val)
|
|
{
|
|
int rc = -RIG_ENIMPL;
|
|
|
|
assert(NULL != rig);
|
|
|
|
switch (parm)
|
|
{
|
|
case RIG_PARM_APO:
|
|
break;
|
|
|
|
case RIG_PARM_TIME:
|
|
break;
|
|
|
|
case RIG_PARM_BAT:
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
};
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_get_parm(RIG *rig, setting_t parm, value_t *val)
|
|
{
|
|
int rc = -RIG_ENIMPL;
|
|
|
|
assert(NULL != rig);
|
|
assert(NULL != val);
|
|
|
|
switch (parm)
|
|
{
|
|
case RIG_PARM_APO:
|
|
break;
|
|
|
|
case RIG_PARM_TIME:
|
|
break;
|
|
|
|
case RIG_PARM_BAT:
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
};
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_set_mem(RIG *rig, vfo_t vfo, int ch)
|
|
{
|
|
int rc = RIG_OK;
|
|
|
|
struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) rig->state.priv;
|
|
|
|
if (RIG_VFO_MEM == priv->curr_vfo)
|
|
{
|
|
priv->curr = &priv->mem[ ch ];
|
|
}
|
|
else
|
|
{
|
|
priv->curr->channel_num = ch;
|
|
}
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: ch %d\n", __func__, ch);
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_get_mem(RIG *rig, vfo_t vfo, int *ch)
|
|
{
|
|
int rc = RIG_OK;
|
|
|
|
struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) rig->state.priv;
|
|
channel_t *curr = priv->curr;
|
|
|
|
assert(NULL != ch);
|
|
|
|
*ch = curr->channel_num;
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: ch %d\n", __func__, *ch);
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op)
|
|
{
|
|
int rc = -RIG_ENIMPL;
|
|
|
|
assert(NULL != rig);
|
|
|
|
switch (op)
|
|
{
|
|
case RIG_OP_CPY:
|
|
rc = -RIG_ENIMPL;
|
|
break;
|
|
|
|
case RIG_OP_XCHG:
|
|
rc = -RIG_ENIMPL;
|
|
break;
|
|
|
|
case RIG_OP_TOGGLE:
|
|
rc = sendIRCode(rig, IR_VFO);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
};
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch)
|
|
{
|
|
int rc = -RIG_ENIMPL;
|
|
|
|
assert(NULL != rig);
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd)
|
|
{
|
|
int rc = RIG_OK;
|
|
unsigned char v;
|
|
|
|
assert(NULL != rig);
|
|
assert(NULL != dcd);
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
rc = readByte(rig, WORKING, BITS + 2, &v);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
if ((v & 0x02))
|
|
{
|
|
if ((v & 0x01)) /* low bit set if Squelch is NOT active/open */
|
|
{
|
|
*dcd = RIG_DCD_OFF;
|
|
}
|
|
else
|
|
{
|
|
*dcd = RIG_DCD_ON;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*dcd = RIG_DCD_ON;
|
|
}
|
|
}
|
|
|
|
rc = lockRx(rig, LOCK_0);
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts)
|
|
{
|
|
int rc = RIG_OK;
|
|
|
|
assert(NULL != rig);
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
/* Scale parameter */
|
|
unsigned short v = (unsigned short)((double)(ts + 1) / HZ_PER_STEP);
|
|
|
|
rc = writeShort(rig, WORKING, CHNSTP, v); /* chnstp */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
rc = execRoutine(rig, SET_ALL);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: chnstp %d (%d)\n", __func__, (int)ts, v);
|
|
}
|
|
|
|
if (RIG_OK == rc) { rc = lockRx(rig, LOCK_0); }
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* /brief Get receiver tuning step size
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param vfo VFO to operate on
|
|
* /param ts Pointer to tuning step value
|
|
*
|
|
* /return RIG_OK on success
|
|
*/
|
|
static int ar7030p_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts)
|
|
{
|
|
int rc = RIG_OK;
|
|
unsigned short v;
|
|
|
|
assert(NULL != rig);
|
|
assert(NULL != ts);
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
rc = readShort(rig, WORKING, CHNSTP, &v); /* chnstp */
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
double x = (double) v;
|
|
*ts = (shortfreq_t)(x * HZ_PER_STEP);
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: step= %d\n", __func__, (int)*ts);
|
|
}
|
|
|
|
rc = lockRx(rig, LOCK_0);
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* /brief Set receiver power status
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param status Power status to set
|
|
*
|
|
* /return RIG_OK on success
|
|
*/
|
|
static int ar7030p_set_powerstat(RIG *rig, powerstat_t status)
|
|
{
|
|
int rc;
|
|
|
|
assert(NULL != rig);
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
switch (status)
|
|
{
|
|
case RIG_POWER_OFF:
|
|
break;
|
|
|
|
case RIG_POWER_ON:
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
lockRx(rig, LOCK_0);
|
|
}
|
|
|
|
return (-RIG_ENIMPL);
|
|
}
|
|
|
|
/*
|
|
* /brief Get receiver power status
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param status Pointer to power status value
|
|
*
|
|
* /return RIG_OK on success
|
|
*/
|
|
static int ar7030p_get_powerstat(RIG *rig, powerstat_t *status)
|
|
{
|
|
int rc = RIG_OK;
|
|
unsigned char v;
|
|
|
|
assert(NULL != rig);
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
rc = readByte(rig, WORKING, PDFLGS, &v);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
if (0 == (v & 0x01))
|
|
{
|
|
*status = RIG_POWER_OFF;
|
|
}
|
|
else
|
|
{
|
|
*status = RIG_POWER_ON;
|
|
}
|
|
}
|
|
|
|
rc = lockRx(rig, LOCK_0);
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* /brief Reset receiver
|
|
*
|
|
* /param rig Pointer to rig struct
|
|
* /param reset Reset operation to perform
|
|
*
|
|
* /return RIG_OK on success
|
|
*/
|
|
static int ar7030p_reset(RIG *rig, reset_t reset)
|
|
{
|
|
int rc = RIG_OK;
|
|
|
|
assert(NULL != rig);
|
|
|
|
switch (reset)
|
|
{
|
|
case RIG_RESET_SOFT:
|
|
rc = execRoutine(rig, RESET);
|
|
break;
|
|
|
|
default:
|
|
rc = -RIG_EINVAL;
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
static int ar7030p_set_func(RIG *rig, vfo_t vfo, setting_t func,
|
|
int status)
|
|
{
|
|
assert(NULL != rig);
|
|
|
|
return (-RIG_ENIMPL);
|
|
}
|
|
|
|
static int ar7030p_get_func(RIG *rig, vfo_t vfo, setting_t func,
|
|
int *status)
|
|
{
|
|
assert(NULL != rig);
|
|
assert(NULL != status);
|
|
|
|
return (-RIG_ENIMPL);
|
|
}
|
|
|
|
static int ar7030p_decode_event(RIG *rig)
|
|
{
|
|
assert(NULL != rig);
|
|
|
|
return (-RIG_ENIMPL);
|
|
}
|
|
|
|
static int ar7030p_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan)
|
|
{
|
|
assert(NULL != rig);
|
|
assert(NULL != chan);
|
|
|
|
return (-RIG_ENIMPL);
|
|
}
|
|
|
|
static int ar7030p_get_channel(RIG *rig, vfo_t vfo, channel_t *chan,
|
|
int read_only)
|
|
{
|
|
int rc = RIG_OK;
|
|
unsigned char v;
|
|
unsigned int f;
|
|
unsigned char *p = NULL;
|
|
int ch;
|
|
struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *)rig->state.priv;
|
|
channel_t *curr = priv->curr;
|
|
|
|
assert(NULL != chan);
|
|
|
|
ch = curr->channel_num;
|
|
|
|
rc = lockRx(rig, LOCK_1);
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
int i;
|
|
|
|
/* Squelch values */
|
|
/* TODO - fix magic numbers */
|
|
if (100 > ch)
|
|
{
|
|
rc = readByte(rig, BBRAM, (MEM_SQ + ch), &v); /* mem_sq */
|
|
}
|
|
else if (176 > ch)
|
|
{
|
|
rc = readByte(rig, EEPROM2, (MEX_SQ + (ch * 16)), &v); /* mex_sq */
|
|
}
|
|
else
|
|
{
|
|
rc = readByte(rig, EEPROM3, (MEY_SQ + ((ch - 176) * 16)), &v); /* mey_sq */
|
|
}
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
// cppcheck-suppress *
|
|
chan->levels[ LVL_SQL ].f = (float) v / 255.0;
|
|
}
|
|
|
|
/* Frequency, mode and filter values */
|
|
if (100 > ch)
|
|
{
|
|
rc = read3Bytes(rig, EEPROM1, (MEM_FR + (ch * 4)), &f); /* mem_fr */
|
|
|
|
if (RIG_OK == rc) { rc = readByte(rig, EEPROM1, (MEM_MD + (ch * 4)), &v); } /* mem_md */
|
|
}
|
|
else
|
|
{
|
|
rc = read3Bytes(rig, EEPROM2, (MEX_FR + ((ch - 100) * 4)), &f); /* mex_fr */
|
|
|
|
if (RIG_OK == rc) { rc = readByte(rig, EEPROM2, (MEX_MD + ((ch - 100) * 4)), &v); } /* mex_md */
|
|
}
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
chan->freq = ddsToHz(f);
|
|
chan->mode = modeToHamlib((v & 0x07));
|
|
chan->width = getFilterBW(rig, ((v & 0x70) >> 4));
|
|
|
|
if ((v & 0x80) >> 7)
|
|
{
|
|
chan->flags = RIG_CHFLAG_SKIP;
|
|
}
|
|
else
|
|
{
|
|
chan->flags = RIG_CHFLAG_NONE;
|
|
}
|
|
}
|
|
|
|
/* PBT values */
|
|
if (100 > ch)
|
|
{
|
|
rc = readByte(rig, EEPROM1, (MEM_PB + ch), &v); /* mem_pb */
|
|
}
|
|
else if (176 > ch)
|
|
{
|
|
rc = readByte(rig, EEPROM2, (MEX_PB + (ch * 16)), &v); /* mex_pb */
|
|
}
|
|
else
|
|
{
|
|
rc = readByte(rig, EEPROM3, (MEY_PB + ((ch - 176) * 16)), &v); /* mey_pb */
|
|
}
|
|
|
|
if (RIG_OK == rc)
|
|
{
|
|
chan->levels[ LVL_PBT_IN ].f = pbsToHz(v);
|
|
}
|
|
|
|
/* Memory ID values */
|
|
p = (unsigned char *) chan->channel_desc;
|
|
|
|
for (i = 0; i < 14; i++)
|
|
{
|
|
if (176 > ch)
|
|
{
|
|
rc = readByte(rig, EEPROM2, (MEX_ID + (ch * 16) + i), p++); /* mex_id */
|
|
}
|
|
else
|
|
{
|
|
rc = readByte(rig, EEPROM3, (MEY_ID + ((ch - 176) * 16) + i),
|
|
p++); /* mey_id */
|
|
}
|
|
|
|
if (RIG_OK != rc)
|
|
{
|
|
p = (unsigned char *) chan->channel_desc;
|
|
break;
|
|
}
|
|
}
|
|
|
|
*p++ = '\0';
|
|
|
|
rc = lockRx(rig, LOCK_0);
|
|
}
|
|
|
|
if (!read_only)
|
|
{
|
|
// Set rig to channel values
|
|
rig_debug(RIG_DEBUG_ERR,
|
|
"%s: please contact hamlib mailing list to implement this\n", __func__);
|
|
rig_debug(RIG_DEBUG_ERR,
|
|
"%s: need to know if rig updates when channel read or not\n", __func__);
|
|
return -RIG_ENIMPL;
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
const struct rig_caps ar7030p_caps =
|
|
{
|
|
RIG_MODEL(RIG_MODEL_AR7030P),
|
|
.model_name = "AR7030 Plus",
|
|
.mfg_name = "AOR",
|
|
.version = "20200319.0",
|
|
.copyright = "LGPL",
|
|
.status = RIG_STATUS_BETA,
|
|
.rig_type = RIG_TYPE_RECEIVER,
|
|
|
|
.dcd_type = RIG_DCD_RIG,
|
|
|
|
.port_type = RIG_PORT_SERIAL,
|
|
.serial_rate_min = 1200,
|
|
.serial_rate_max = 1200,
|
|
.serial_data_bits = 8,
|
|
.serial_stop_bits = 1,
|
|
.serial_parity = RIG_PARITY_NONE,
|
|
.serial_handshake = RIG_HANDSHAKE_NONE,
|
|
.write_delay = 0,
|
|
.post_write_delay = 12,
|
|
.timeout = 650,
|
|
.retry = 0,
|
|
|
|
.has_get_func = AR7030P_FUNC,
|
|
.has_set_func = AR7030P_FUNC,
|
|
.has_get_level = AR7030P_LEVEL,
|
|
.has_set_level = RIG_LEVEL_SET(AR7030P_LEVEL),
|
|
.has_get_parm = AR7030P_PARM,
|
|
.has_set_parm = RIG_PARM_SET(AR7030P_PARM),
|
|
|
|
.level_gran = {
|
|
[LVL_PREAMP] = {.min = {.i = 0}, .max = {.i = 10} },
|
|
[LVL_ATT] = {.min = {.i = 0}, .max = {.i = 20} },
|
|
[LVL_RF] = {.min = {.f = 0.0}, .max = {.f = 1.0} },
|
|
[LVL_AF] = {.min = {.f = 0.0}, .max = {.f = 1.0} },
|
|
[LVL_SQL] = {.min = {.f = 0.0}, .max = {.f = 1.0} },
|
|
[LVL_IF] = {.min = {.i = 255}, .max = {.i = 0} },
|
|
[LVL_PBT_IN] = {.min = {.f = -4248.0}, .max = {.f = 4248.0} },
|
|
[LVL_CWPITCH] = {.min = {.i = -4248}, .max = {.i = 4248} },
|
|
[LVL_NOTCHF] = {.min = {.i = 0}, .max = {.i = 10000} },
|
|
[LVL_AGC] = {.min = {.i = 0}, .max = {.i = 10} },
|
|
[LVL_BALANCE] = {.min = {.f = -1.0}, .max = {.f = 1.0} },
|
|
[LVL_RAWSTR] = {.min = {.i = 0}, .max = {.i = 255} },
|
|
[LVL_STRENGTH] = {.min = {.i = 0}, .max = {.i = 255} },
|
|
},
|
|
|
|
.extparms = NULL,
|
|
.extlevels = NULL,
|
|
|
|
.parm_gran = {
|
|
[PARM_APO] = {.min = {.i = 1}, .max = {.i = 86400} },
|
|
[PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86400} },
|
|
[PARM_BAT] = {.min = {.f = 0.0}, .max = {.f = 1.0} },
|
|
},
|
|
|
|
.preamp = {10, RIG_DBLST_END,},
|
|
.attenuator = {10, 20, RIG_DBLST_END,},
|
|
.max_rit = Hz(0),
|
|
.max_xit = Hz(0),
|
|
.max_ifshift = Hz(4248),
|
|
.announces = RIG_ANN_NONE,
|
|
.vfo_ops = AR7030P_VFO_OPS,
|
|
.scan_ops = RIG_SCAN_STOP | RIG_SCAN_MEM | RIG_SCAN_VFO,
|
|
.targetable_vfo = 0,
|
|
.transceive = RIG_TRN_OFF,
|
|
.bank_qty = 0,
|
|
.chan_desc_sz = 14,
|
|
|
|
.chan_list = {{0, 399, RIG_MTYPE_MEM, AR7030P_MEM_CAP}, RIG_CHAN_END,},
|
|
|
|
.rx_range_list1 = {
|
|
{
|
|
kHz(10), kHz(32010), AR7030P_MODES, -1, -1,
|
|
AR7030P_VFO
|
|
},
|
|
RIG_FRNG_END,
|
|
},
|
|
.tx_range_list1 = {RIG_FRNG_END,},
|
|
|
|
.rx_range_list2 = {
|
|
{
|
|
kHz(10), kHz(32010), AR7030P_MODES, -1, -1,
|
|
AR7030P_VFO
|
|
},
|
|
RIG_FRNG_END,
|
|
},
|
|
.tx_range_list2 = {RIG_FRNG_END,},
|
|
|
|
.tuning_steps = {
|
|
{AR7030P_MODES, Hz(10)},
|
|
{AR7030P_MODES, Hz(20)},
|
|
{AR7030P_MODES, Hz(50)},
|
|
{AR7030P_MODES, Hz(100)},
|
|
{AR7030P_MODES, Hz(200)},
|
|
{AR7030P_MODES, Hz(500)},
|
|
{AR7030P_MODES, kHz(1)},
|
|
{AR7030P_MODES, kHz(2)},
|
|
{AR7030P_MODES, kHz(5)},
|
|
{AR7030P_MODES, kHz(6.25)},
|
|
{AR7030P_MODES, kHz(9)},
|
|
{AR7030P_MODES, kHz(10)},
|
|
{AR7030P_MODES, Hz(12500)},
|
|
{AR7030P_MODES, kHz(20)},
|
|
{AR7030P_MODES, kHz(25)},
|
|
RIG_TS_END,
|
|
},
|
|
|
|
.filters = {
|
|
{RIG_MODE_FM, kHz(9.5)},
|
|
{RIG_MODE_FM, kHz(0)},
|
|
{RIG_MODE_FM, kHz(0)},
|
|
{RIG_MODE_AMS, kHz(6.5)},
|
|
{RIG_MODE_AMS, kHz(5.3)},
|
|
{RIG_MODE_AMS, kHz(9.5)},
|
|
{RIG_MODE_AM, kHz(5.3)},
|
|
{RIG_MODE_AM, kHz(3.7)},
|
|
{RIG_MODE_AM, kHz(6.5)},
|
|
{RIG_MODE_SSB, kHz(2.0)},
|
|
{RIG_MODE_SSB, kHz(1.4)},
|
|
{RIG_MODE_SSB, kHz(3.7)},
|
|
{RIG_MODE_CW, kHz(1.4)},
|
|
{RIG_MODE_CW, kHz(0)},
|
|
{RIG_MODE_CW, kHz(2.0)},
|
|
{RIG_MODE_RTTY, kHz(1.4)},
|
|
{RIG_MODE_RTTY, kHz(0)},
|
|
{RIG_MODE_RTTY, kHz(2.0)},
|
|
RIG_FLT_END,
|
|
},
|
|
|
|
.str_cal = AR7030P_STR_CAL,
|
|
.cfgparams = NULL,
|
|
.priv = (void *)& ar7030p_priv_caps,
|
|
|
|
.rig_init = ar7030p_init,
|
|
.rig_cleanup = ar7030p_cleanup,
|
|
.rig_open = ar7030p_open,
|
|
.rig_close = ar7030p_close,
|
|
.set_freq = ar7030p_set_freq,
|
|
.get_freq = ar7030p_get_freq,
|
|
.set_mode = ar7030p_set_mode,
|
|
.get_mode = ar7030p_get_mode,
|
|
.set_vfo = ar7030p_set_vfo,
|
|
.get_vfo = ar7030p_get_vfo,
|
|
|
|
.get_dcd = ar7030p_get_dcd,
|
|
|
|
.set_ts = ar7030p_set_ts,
|
|
.get_ts = ar7030p_get_ts,
|
|
|
|
.set_powerstat = ar7030p_set_powerstat,
|
|
.get_powerstat = ar7030p_get_powerstat,
|
|
.reset = ar7030p_reset,
|
|
|
|
.set_level = ar7030p_set_level,
|
|
.get_level = ar7030p_get_level,
|
|
.set_func = ar7030p_set_func,
|
|
.get_func = ar7030p_get_func,
|
|
.set_parm = ar7030p_set_parm,
|
|
.get_parm = ar7030p_get_parm,
|
|
|
|
.set_ext_level = RIG_FUNC_NONE,
|
|
.get_ext_level = RIG_FUNC_NONE,
|
|
.set_ext_parm = RIG_FUNC_NONE,
|
|
.get_ext_parm = RIG_FUNC_NONE,
|
|
.set_conf = RIG_FUNC_NONE,
|
|
.get_conf = RIG_FUNC_NONE,
|
|
|
|
.set_mem = ar7030p_set_mem,
|
|
.get_mem = ar7030p_get_mem,
|
|
.vfo_op = ar7030p_vfo_op,
|
|
.scan = ar7030p_scan,
|
|
|
|
.decode_event = ar7030p_decode_event,
|
|
.set_channel = ar7030p_set_channel,
|
|
.get_channel = ar7030p_get_channel,
|
|
.get_info = ar7030p_get_info,
|
|
|
|
.set_chan_all_cb = RIG_FUNC_NONE,
|
|
.get_chan_all_cb = RIG_FUNC_NONE,
|
|
.set_mem_all_cb = RIG_FUNC_NONE,
|
|
.get_mem_all_cb = RIG_FUNC_NONE,
|
|
|
|
};
|