kopia lustrzana https://github.com/Hamlib/Hamlib
Better set frequency semantics for the IC-910(h)
Allows for the optional 23cms module. No longer tries to preserve the pre-amp/attn/bandwidth settings as the does this (correctly) already.Hamlib-3.1
rodzic
48102caeaa
commit
398bd3ccaa
515
icom/ic910.c
515
icom/ic910.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Hamlib CI-V backend - description of IC-910 (VHF/UHF All-Mode Tranceiver)
|
||||
* Contributed by Francois Retief <fgretief@sun.ac.za>
|
||||
* Hamlib CI-V backend - description of IC-910 (VHF/UHF All-Mode
|
||||
* Tranceiver) Contributed by Francois Retief <fgretief@sun.ac.za>
|
||||
* Copyright (c) 2000-2010 by Stephane Fillod
|
||||
*
|
||||
*
|
||||
|
@ -41,24 +41,24 @@
|
|||
#ifdef HAVE_WEIRD_IC910_MODES
|
||||
static int ic910_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||
{
|
||||
/* FIX: The IC-910 has "Set FM" = 4, which is RTTY in for other radios */
|
||||
if (mode == RIG_MODE_FM) {
|
||||
mode = RIG_MODE_RTTY;
|
||||
}
|
||||
/* FIX: The IC-910 has "Set FM" = 4, which is RTTY in for other radios */
|
||||
if (mode == RIG_MODE_FM) {
|
||||
mode = RIG_MODE_RTTY;
|
||||
}
|
||||
|
||||
return icom_set_mode(rig, vfo, mode, width);
|
||||
return icom_set_mode(rig, vfo, mode, width);
|
||||
}
|
||||
|
||||
static int ic910_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
||||
{
|
||||
/* FIX: The IC-910 has "Set FM" = 4, which is RTTY in for other radios */
|
||||
int retval = icom_get_mode(rig, vfo, mode, width);
|
||||
/* FIX: The IC-910 has "Set FM" = 4, which is RTTY in for other radios */
|
||||
int retval = icom_get_mode(rig, vfo, mode, width);
|
||||
|
||||
if (*mode == RIG_MODE_RTTY) {
|
||||
*mode = RIG_MODE_FM;
|
||||
}
|
||||
if (*mode == RIG_MODE_RTTY) {
|
||||
*mode = RIG_MODE_FM;
|
||||
}
|
||||
|
||||
return retval;
|
||||
return retval;
|
||||
}
|
||||
#endif /* HAVE_WEIRD_IC910_MODES */
|
||||
|
||||
|
@ -69,126 +69,149 @@ static int ic910_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
|||
|
||||
static int compareFrequencies(RIG *rig, freq_t freq1, freq_t freq2)
|
||||
{
|
||||
int freq1band = 0, freq2band = 0;
|
||||
freq_range_t noband = RIG_FRNG_END;
|
||||
int freq1band = 0, freq2band = 0;
|
||||
freq_range_t noband = RIG_FRNG_END;
|
||||
|
||||
while (rig->caps->rx_range_list1[freq1band].start != noband.start) {
|
||||
if (freq1 >= rig->caps->rx_range_list1[freq1band].start &&
|
||||
freq1 <= rig->caps->rx_range_list1[freq1band].end)
|
||||
break;
|
||||
while (rig->caps->rx_range_list1[freq1band].start != noband.start) {
|
||||
if (freq1 >= rig->caps->rx_range_list1[freq1band].start &&
|
||||
freq1 <= rig->caps->rx_range_list1[freq1band].end)
|
||||
break;
|
||||
|
||||
++freq1band;
|
||||
//fprintf(stderr, "%i\n", freq1band);
|
||||
}
|
||||
++freq1band;
|
||||
//fprintf(stderr, "%i\n", freq1band);
|
||||
}
|
||||
|
||||
while (rig->caps->rx_range_list1[freq2band].start != noband.start) {
|
||||
if (freq2 >= rig->caps->rx_range_list1[freq2band].start &&
|
||||
freq2 <= rig->caps->rx_range_list1[freq2band].end)
|
||||
break;
|
||||
while (rig->caps->rx_range_list1[freq2band].start != noband.start) {
|
||||
if (freq2 >= rig->caps->rx_range_list1[freq2band].start &&
|
||||
freq2 <= rig->caps->rx_range_list1[freq2band].end)
|
||||
break;
|
||||
|
||||
++freq2band;
|
||||
}
|
||||
++freq2band;
|
||||
}
|
||||
|
||||
if (freq2band == freq1band) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/* swaps main and sub band - but preserves PREAMP, MODE
|
||||
* they are also exchanged, but we do not want that
|
||||
*/
|
||||
|
||||
static int icom_swap_bands(RIG *rig)
|
||||
{
|
||||
/* TODO: actually use retval! */
|
||||
int retval = 0;
|
||||
rmode_t mmode, smode; /* used to store the mode */
|
||||
pbwidth_t mwidth, swidth; /* used to store the width */
|
||||
value_t mpreamp, spreamp; /* used to store preamp */
|
||||
value_t matt, satt; /* used to store attenuation */
|
||||
|
||||
/* main band get values */
|
||||
icom_set_vfo(rig, RIG_VFO_MAIN);
|
||||
/* get the mode, width, preamp */
|
||||
icom_get_mode(rig, RIG_VFO_CURR, &mmode, &mwidth);
|
||||
icom_get_level(rig, RIG_VFO_CURR, RIG_LEVEL_PREAMP, &mpreamp);
|
||||
icom_get_level(rig, RIG_VFO_CURR, RIG_LEVEL_ATT, &matt);
|
||||
|
||||
/* sub band get values */
|
||||
icom_set_vfo(rig, RIG_VFO_SUB);
|
||||
/* get the mode, width, preamp, att */
|
||||
icom_get_mode(rig, RIG_VFO_CURR, &smode, &swidth);
|
||||
icom_get_level(rig, RIG_VFO_CURR, RIG_LEVEL_PREAMP, &spreamp);
|
||||
icom_get_level(rig, RIG_VFO_CURR, RIG_LEVEL_ATT, &satt);
|
||||
|
||||
/* now, we can exchange the bands */
|
||||
icom_vfo_op(rig, RIG_VFO_CURR, RIG_OP_XCHG);
|
||||
|
||||
/* restore the sub vales NOTE: sub band is still active */
|
||||
/* set the mode, width, preamp */
|
||||
icom_set_mode(rig, RIG_VFO_CURR, smode, swidth);
|
||||
icom_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_PREAMP, spreamp);
|
||||
icom_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_ATT, satt);
|
||||
|
||||
/* restore main band values */
|
||||
icom_set_vfo(rig, RIG_VFO_MAIN);
|
||||
/* set the mode, width, preamp */
|
||||
icom_set_mode(rig, RIG_VFO_CURR, mmode, mwidth);
|
||||
icom_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_PREAMP, mpreamp);
|
||||
icom_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_ATT, matt);
|
||||
|
||||
return retval;
|
||||
if (freq2band == freq1band) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static int ic910_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
||||
{
|
||||
int retval;
|
||||
freq_t otherfreq;
|
||||
freq_t oldfreq;
|
||||
int retval;
|
||||
freq_t otherfreq;
|
||||
freq_t origfreq;
|
||||
|
||||
retval = icom_get_freq(rig, vfo, &oldfreq);
|
||||
|
||||
if (retval != RIG_OK) return retval;
|
||||
|
||||
if (!compareFrequencies(rig, freq, oldfreq)) {
|
||||
/* we are on the wrong band */
|
||||
if (vfo == RIG_VFO_CURR) {
|
||||
/* try to detect active subband */
|
||||
icom_set_vfo(rig, RIG_VFO_SUB);
|
||||
|
||||
retval = icom_get_freq(rig, RIG_VFO_CURR, &otherfreq);
|
||||
|
||||
if (retval != RIG_OK) return retval;
|
||||
|
||||
if (otherfreq == oldfreq) {
|
||||
/* were already in subband */
|
||||
vfo = RIG_VFO_SUB;
|
||||
icom_set_vfo(rig, RIG_VFO_MAIN);
|
||||
retval = icom_get_freq(rig, RIG_VFO_CURR, &otherfreq);
|
||||
|
||||
if (retval != RIG_OK) return retval;
|
||||
} else {
|
||||
/* we were in mainband */
|
||||
vfo = RIG_VFO_MAIN;
|
||||
}
|
||||
} else {
|
||||
/* get the freq of the other band */
|
||||
if (vfo == RIG_VFO_MAIN)
|
||||
icom_set_vfo(rig, RIG_VFO_SUB);
|
||||
else
|
||||
icom_set_vfo(rig, RIG_VFO_MAIN);
|
||||
|
||||
retval = icom_get_freq(rig, RIG_VFO_CURR, &otherfreq);
|
||||
|
||||
if (retval != RIG_OK) return retval;
|
||||
}
|
||||
|
||||
if (compareFrequencies(rig, freq, otherfreq))
|
||||
icom_swap_bands(rig);
|
||||
|
||||
icom_set_vfo(rig, vfo);
|
||||
}
|
||||
|
||||
return icom_set_freq(rig, RIG_VFO_CURR, freq);
|
||||
if ((retval = icom_get_freq(rig, RIG_VFO_CURR, &origfreq)) != RIG_OK) return retval;
|
||||
if (compareFrequencies (rig, freq, origfreq))
|
||||
{
|
||||
/* correct band already */
|
||||
if (RIG_VFO_A == vfo || RIG_VFO_B == vfo)
|
||||
{
|
||||
/* switch to desired VFO and read its frequency */
|
||||
if ((retval = icom_set_vfo (rig, vfo)) != RIG_OK) return retval;
|
||||
if ((retval = icom_get_freq(rig, vfo, &otherfreq)) != RIG_OK) return retval;
|
||||
retval = icom_set_freq (rig, RIG_VFO_CURR, freq);
|
||||
if (otherfreq != origfreq)
|
||||
{
|
||||
/* swap VFOs back as original was the other one */
|
||||
icom_set_vfo (rig, RIG_VFO_A == vfo ? RIG_VFO_B : RIG_VFO_A);
|
||||
}
|
||||
}
|
||||
else if (RIG_VFO_MAIN == vfo || RIG_VFO_SUB == vfo)
|
||||
{
|
||||
/* switch to the desired of MAIN and SUB and read its frequency */
|
||||
if ((retval = icom_set_vfo (rig, vfo)) != RIG_OK) return retval;
|
||||
if ((retval = icom_get_freq(rig, vfo, &otherfreq)) != RIG_OK) return retval;
|
||||
if (otherfreq != origfreq)
|
||||
{
|
||||
/* started on a different so band exchange MAIN and SUB */
|
||||
if ((retval = icom_vfo_op(rig, RIG_VFO_CURR, RIG_OP_XCHG)) != RIG_OK) return retval;
|
||||
retval = icom_set_freq (rig, RIG_VFO_CURR, freq);
|
||||
/* swap MAIN/SUB back as original was the other one */
|
||||
icom_set_vfo (rig, RIG_VFO_MAIN == vfo ? RIG_VFO_SUB : RIG_VFO_MAIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* already correct one of MAIN and SUB */
|
||||
retval = icom_set_freq (rig, RIG_VFO_CURR, freq);
|
||||
}
|
||||
}
|
||||
else if (RIG_VFO_CURR == vfo)
|
||||
{
|
||||
retval = icom_set_freq (rig, RIG_VFO_CURR, freq);
|
||||
}
|
||||
else retval = -RIG_EVFO;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wrong band */
|
||||
if (RIG_VFO_A == vfo || RIG_VFO_B == vfo)
|
||||
{
|
||||
/* try and set frequency, may fail if band is already on other of MAIN/SUB */
|
||||
retval = icom_set_freq (rig, RIG_VFO_CURR, freq);
|
||||
if (-RIG_ERJCTED == retval)
|
||||
{
|
||||
/* exchange MAIN & SUB */
|
||||
if ((retval = icom_vfo_op(rig, RIG_VFO_CURR, RIG_OP_XCHG)) != RIG_OK) return retval;
|
||||
if ((retval = icom_get_freq(rig, vfo, &origfreq)) != RIG_OK) return retval;
|
||||
if ((retval = icom_set_vfo (rig, vfo)) != RIG_OK) return retval;
|
||||
if ((retval = icom_get_freq(rig, vfo, &otherfreq)) != RIG_OK) return retval;
|
||||
retval = icom_set_freq (rig, RIG_VFO_CURR, freq);
|
||||
if (-RIG_ERJCTED == retval)
|
||||
{
|
||||
/* band not fitted so swap MAIN & SUB back and give up */
|
||||
icom_vfo_op(rig, RIG_VFO_CURR, RIG_OP_XCHG);
|
||||
return retval;
|
||||
}
|
||||
else if (retval != RIG_OK) return retval;
|
||||
if (otherfreq != origfreq)
|
||||
{
|
||||
/* swap VFOs back as original was the other one */
|
||||
icom_set_vfo (rig, RIG_VFO_A == vfo ? RIG_VFO_B : RIG_VFO_A);
|
||||
}
|
||||
/* we do not exchange bands back as this is taken to
|
||||
mean set VFOA/B on MAIN to the specified frequency
|
||||
as Hamlib does not recognize A on MAIN or B on SUB
|
||||
etc. This is probably reasonable since we cannot Tx
|
||||
on SUB */
|
||||
return retval;
|
||||
}
|
||||
/* we changed band to the "third band" which always makes
|
||||
VFO A current so just make the requested one the
|
||||
specified frequency as well if it is VFO B. There is no
|
||||
way of going to the "third band" without changing VFO
|
||||
A */
|
||||
if (RIG_VFO_B == vfo) {
|
||||
if ((retval = icom_set_vfo (rig, vfo)) != RIG_OK) return retval;
|
||||
retval = icom_set_freq (rig, RIG_VFO_CURR, freq);
|
||||
icom_set_vfo (rig, RIG_VFO_A);
|
||||
}
|
||||
}
|
||||
else if (RIG_VFO_MAIN == vfo || RIG_VFO_SUB == vfo)
|
||||
{
|
||||
if ((retval = icom_set_vfo (rig, vfo)) != RIG_OK) return retval;
|
||||
if ((retval = icom_get_freq(rig, vfo, &otherfreq)) != RIG_OK) return retval;
|
||||
retval = icom_set_freq (rig, RIG_VFO_CURR, freq);
|
||||
if (-RIG_ERJCTED == retval)
|
||||
{
|
||||
/* required band is on other of MAIN or SUB */
|
||||
if ((retval = icom_vfo_op(rig, RIG_VFO_CURR, RIG_OP_XCHG)) != RIG_OK) return retval;
|
||||
retval = icom_set_freq (rig, RIG_VFO_CURR, freq);
|
||||
}
|
||||
else if (retval != RIG_OK) return retval;
|
||||
if (otherfreq != origfreq)
|
||||
{
|
||||
/* started on other of MAIN & SUB so switch back */
|
||||
icom_set_vfo (rig,
|
||||
RIG_VFO_MAIN == vfo ?
|
||||
RIG_VFO_SUB : RIG_VFO_MAIN);
|
||||
}
|
||||
}
|
||||
else if (RIG_VFO_CURR == vfo)
|
||||
{
|
||||
retval = icom_set_freq (rig, RIG_VFO_CURR, freq);
|
||||
}
|
||||
else retval = -RIG_EVFO;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -196,16 +219,16 @@ static int ic910_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
|||
* (1 - normal, 2 - narrow)
|
||||
*/
|
||||
static int ic910_r2i_mode(RIG *rig, rmode_t mode, pbwidth_t width,
|
||||
unsigned char *md, signed char *pd)
|
||||
unsigned char *md, signed char *pd)
|
||||
{
|
||||
int err;
|
||||
int err;
|
||||
|
||||
err = rig2icom_mode(rig, mode, width, md, pd);
|
||||
err = rig2icom_mode(rig, mode, width, md, pd);
|
||||
|
||||
if (*pd == PD_NARROW_3)
|
||||
*pd = PD_NARROW_2;
|
||||
if (*pd == PD_NARROW_3)
|
||||
*pd = PD_NARROW_2;
|
||||
|
||||
return err;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
@ -252,141 +275,141 @@ static int ic910_r2i_mode(RIG *rig, rmode_t mode, pbwidth_t width,
|
|||
RIG_LEVEL_ATT| \
|
||||
RIG_LEVEL_PREAMP)
|
||||
|
||||
#define IC910_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */
|
||||
#define IC910_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
static const struct icom_priv_caps ic910_priv_caps = {
|
||||
0x60, /* default address */
|
||||
0, /* 731 mode */
|
||||
0, /* no XCHG */
|
||||
ic910_ts_sc_list,
|
||||
.r2i_mode = ic910_r2i_mode
|
||||
0x60, /* default address */
|
||||
0, /* 731 mode */
|
||||
0, /* no XCHG */
|
||||
ic910_ts_sc_list,
|
||||
.r2i_mode = ic910_r2i_mode
|
||||
};
|
||||
|
||||
const struct rig_caps ic910_caps = {
|
||||
.rig_model = RIG_MODEL_IC910,
|
||||
.model_name = "IC-910",
|
||||
.mfg_name = "Icom",
|
||||
.version = BACKEND_VER ".1",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_BETA,
|
||||
.rig_type = RIG_TYPE_TRANSCEIVER,
|
||||
.ptt_type = RIG_PTT_NONE,
|
||||
.dcd_type = RIG_DCD_RIG,
|
||||
.port_type = RIG_PORT_SERIAL,
|
||||
.serial_rate_min = 300,
|
||||
.serial_rate_max = 19200,
|
||||
.serial_data_bits = 8,
|
||||
.serial_stop_bits = 1,
|
||||
.serial_parity = RIG_PARITY_NONE,
|
||||
.serial_handshake = RIG_HANDSHAKE_NONE,
|
||||
.write_delay = 0,
|
||||
.post_write_delay = 0,
|
||||
.timeout = 1000,
|
||||
.retry = 3,
|
||||
.has_get_func = IC910_FUNC_ALL,
|
||||
.has_set_func = IC910_FUNC_ALL | RIG_FUNC_RESUME,
|
||||
.has_get_level = IC910_LEVEL_ALL | (RIG_LEVEL_RAWSTR),
|
||||
.has_set_level = IC910_LEVEL_ALL,
|
||||
.has_get_parm = RIG_PARM_NONE,
|
||||
.has_set_parm = RIG_PARM_NONE,
|
||||
.level_gran = {
|
||||
[LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
|
||||
},
|
||||
.parm_gran = {},
|
||||
.ctcss_list = NULL,
|
||||
.dcs_list = NULL,
|
||||
.preamp = { 20, RIG_DBLST_END, },
|
||||
.attenuator = { 20, RIG_DBLST_END, },
|
||||
.max_rit = Hz(0), /* SSB,CW: +-1.0kHz FM: +-5.0kHz */
|
||||
.max_xit = Hz(0),
|
||||
.max_ifshift = Hz(0), /* 1.2kHz manual knob */
|
||||
.targetable_vfo = 0,
|
||||
.vfo_ops = IC910_VFO_OPS,
|
||||
.scan_ops = IC910_SCAN_OPS,
|
||||
.transceive = RIG_TRN_RIG,
|
||||
.bank_qty = 0,
|
||||
.chan_desc_sz = 0,
|
||||
.rig_model = RIG_MODEL_IC910,
|
||||
.model_name = "IC-910",
|
||||
.mfg_name = "Icom",
|
||||
.version = BACKEND_VER ".1",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_BETA,
|
||||
.rig_type = RIG_TYPE_TRANSCEIVER,
|
||||
.ptt_type = RIG_PTT_NONE,
|
||||
.dcd_type = RIG_DCD_RIG,
|
||||
.port_type = RIG_PORT_SERIAL,
|
||||
.serial_rate_min = 300,
|
||||
.serial_rate_max = 19200,
|
||||
.serial_data_bits = 8,
|
||||
.serial_stop_bits = 1,
|
||||
.serial_parity = RIG_PARITY_NONE,
|
||||
.serial_handshake = RIG_HANDSHAKE_NONE,
|
||||
.write_delay = 0,
|
||||
.post_write_delay = 0,
|
||||
.timeout = 1000,
|
||||
.retry = 3,
|
||||
.has_get_func = IC910_FUNC_ALL,
|
||||
.has_set_func = IC910_FUNC_ALL | RIG_FUNC_RESUME,
|
||||
.has_get_level = IC910_LEVEL_ALL | (RIG_LEVEL_RAWSTR),
|
||||
.has_set_level = IC910_LEVEL_ALL,
|
||||
.has_get_parm = RIG_PARM_NONE,
|
||||
.has_set_parm = RIG_PARM_NONE,
|
||||
.level_gran = {
|
||||
[LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } },
|
||||
},
|
||||
.parm_gran = {},
|
||||
.ctcss_list = NULL,
|
||||
.dcs_list = NULL,
|
||||
.preamp = { 20, RIG_DBLST_END, },
|
||||
.attenuator = { 20, RIG_DBLST_END, },
|
||||
.max_rit = Hz(0), /* SSB,CW: +-1.0kHz FM: +-5.0kHz */
|
||||
.max_xit = Hz(0),
|
||||
.max_ifshift = Hz(0), /* 1.2kHz manual knob */
|
||||
.targetable_vfo = RIG_TARGETABLE_FREQ,
|
||||
.vfo_ops = IC910_VFO_OPS,
|
||||
.scan_ops = IC910_SCAN_OPS,
|
||||
.transceive = RIG_TRN_RIG,
|
||||
.bank_qty = 0,
|
||||
.chan_desc_sz = 0,
|
||||
|
||||
.chan_list = {
|
||||
{ 1, 99, RIG_MTYPE_MEM },
|
||||
{ 100, 105, RIG_MTYPE_EDGE },
|
||||
{ 106, 106, RIG_MTYPE_CALL },
|
||||
RIG_CHAN_END,
|
||||
},
|
||||
.chan_list = {
|
||||
{ 1, 99, RIG_MTYPE_MEM },
|
||||
{ 100, 105, RIG_MTYPE_EDGE },
|
||||
{ 106, 106, RIG_MTYPE_CALL },
|
||||
RIG_CHAN_END,
|
||||
},
|
||||
|
||||
.rx_range_list1 = { /* USA */
|
||||
{MHz(144), MHz(148), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
{MHz(430), MHz(450), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
{MHz(1240), MHz(1300), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
RIG_FRNG_END,
|
||||
},
|
||||
.tx_range_list1 = {
|
||||
{MHz(144), MHz(148), IC910_MODES, W(5), W(100), IC910_VFO_ALL},
|
||||
{MHz(430), MHz(450), IC910_MODES, W(5), W(75), IC910_VFO_ALL},
|
||||
{MHz(1240), MHz(1300), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
RIG_FRNG_END,
|
||||
},
|
||||
.rx_range_list1 = { /* USA */
|
||||
{MHz(144), MHz(148), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
{MHz(430), MHz(450), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
{MHz(1240), MHz(1300), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
RIG_FRNG_END,
|
||||
},
|
||||
.tx_range_list1 = {
|
||||
{MHz(144), MHz(148), IC910_MODES, W(5), W(100), IC910_VFO_ALL},
|
||||
{MHz(430), MHz(450), IC910_MODES, W(5), W(75), IC910_VFO_ALL},
|
||||
{MHz(1240), MHz(1300), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
RIG_FRNG_END,
|
||||
},
|
||||
|
||||
.rx_range_list2 = { /* Europe */
|
||||
{MHz(144), MHz(146), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
{MHz(430), MHz(440), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
{MHz(1240), MHz(1300), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
RIG_FRNG_END,
|
||||
},
|
||||
.tx_range_list2 = {
|
||||
{MHz(144), MHz(146), IC910_MODES, W(5), W(100), IC910_VFO_ALL},
|
||||
{MHz(430), MHz(440), IC910_MODES, W(5), W(75), IC910_VFO_ALL},
|
||||
{MHz(1240), MHz(1300), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
RIG_FRNG_END,
|
||||
},
|
||||
.rx_range_list2 = { /* Europe */
|
||||
{MHz(144), MHz(146), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
{MHz(430), MHz(440), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
{MHz(1240), MHz(1300), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
RIG_FRNG_END,
|
||||
},
|
||||
.tx_range_list2 = {
|
||||
{MHz(144), MHz(146), IC910_MODES, W(5), W(100), IC910_VFO_ALL},
|
||||
{MHz(430), MHz(440), IC910_MODES, W(5), W(75), IC910_VFO_ALL},
|
||||
{MHz(1240), MHz(1300), IC910_MODES, -1, -1, IC910_VFO_ALL},
|
||||
RIG_FRNG_END,
|
||||
},
|
||||
|
||||
.tuning_steps = {
|
||||
{RIG_MODE_SSB | RIG_MODE_CW, 1},
|
||||
{RIG_MODE_SSB | RIG_MODE_CW, 10},
|
||||
{RIG_MODE_SSB | RIG_MODE_CW, 50},
|
||||
{RIG_MODE_SSB | RIG_MODE_CW, 100},
|
||||
{RIG_MODE_FM, kHz(0.1)},
|
||||
{RIG_MODE_FM, kHz(5)},
|
||||
{RIG_MODE_FM, kHz(6.25)},
|
||||
{RIG_MODE_FM, kHz(10)},
|
||||
{RIG_MODE_FM, kHz(12.5)},
|
||||
{RIG_MODE_FM, kHz(20)},
|
||||
{RIG_MODE_FM, kHz(25)},
|
||||
{RIG_MODE_FM, kHz(100)},
|
||||
RIG_TS_END,
|
||||
},
|
||||
/* mode/filter list, remember: order matters! */
|
||||
.filters = {
|
||||
{RIG_MODE_CW | RIG_MODE_SSB, kHz(2.3)}, /* builtin */
|
||||
{RIG_MODE_CW, Hz(600)}, /* with optional FL-132/Fl133 CW filters */
|
||||
{RIG_MODE_FM, kHz(15)}, /* builtin */
|
||||
{RIG_MODE_FM, kHz(6)}, /* builtin */
|
||||
RIG_FLT_END,
|
||||
},
|
||||
.str_cal = IC910_STR_CAL,
|
||||
.tuning_steps = {
|
||||
{RIG_MODE_SSB | RIG_MODE_CW, 1},
|
||||
{RIG_MODE_SSB | RIG_MODE_CW, 10},
|
||||
{RIG_MODE_SSB | RIG_MODE_CW, 50},
|
||||
{RIG_MODE_SSB | RIG_MODE_CW, 100},
|
||||
{RIG_MODE_FM, kHz(0.1)},
|
||||
{RIG_MODE_FM, kHz(5)},
|
||||
{RIG_MODE_FM, kHz(6.25)},
|
||||
{RIG_MODE_FM, kHz(10)},
|
||||
{RIG_MODE_FM, kHz(12.5)},
|
||||
{RIG_MODE_FM, kHz(20)},
|
||||
{RIG_MODE_FM, kHz(25)},
|
||||
{RIG_MODE_FM, kHz(100)},
|
||||
RIG_TS_END,
|
||||
},
|
||||
/* mode/filter list, remember: order matters! */
|
||||
.filters = {
|
||||
{RIG_MODE_CW | RIG_MODE_SSB, kHz(2.3)}, /* builtin */
|
||||
{RIG_MODE_CW, Hz(600)}, /* with optional FL-132/Fl133 CW filters */
|
||||
{RIG_MODE_FM, kHz(15)}, /* builtin */
|
||||
{RIG_MODE_FM, kHz(6)}, /* builtin */
|
||||
RIG_FLT_END,
|
||||
},
|
||||
.str_cal = IC910_STR_CAL,
|
||||
|
||||
.priv = (void *)& ic910_priv_caps,
|
||||
.rig_init = icom_init,
|
||||
.rig_cleanup = icom_cleanup,
|
||||
.rig_open = NULL,
|
||||
.rig_close = NULL,
|
||||
.priv = (void *)& ic910_priv_caps,
|
||||
.rig_init = icom_init,
|
||||
.rig_cleanup = icom_cleanup,
|
||||
.rig_open = NULL,
|
||||
.rig_close = NULL,
|
||||
|
||||
.cfgparams = icom_cfg_params,
|
||||
.set_conf = icom_set_conf,
|
||||
.get_conf = icom_get_conf,
|
||||
.cfgparams = icom_cfg_params,
|
||||
.set_conf = icom_set_conf,
|
||||
.get_conf = icom_get_conf,
|
||||
|
||||
.get_freq = icom_get_freq,
|
||||
.set_freq = ic910_set_freq,
|
||||
.get_freq = icom_get_freq,
|
||||
.set_freq = ic910_set_freq,
|
||||
|
||||
#ifdef HAVE_WEIRD_IC910_MODES
|
||||
.get_mode = ic910_get_mode,
|
||||
.set_mode = ic910_set_mode,
|
||||
.get_mode = ic910_get_mode,
|
||||
.set_mode = ic910_set_mode,
|
||||
#else
|
||||
.get_mode = icom_get_mode,
|
||||
.set_mode = icom_set_mode,
|
||||
.get_mode = icom_get_mode,
|
||||
.set_mode = icom_set_mode,
|
||||
#endif
|
||||
|
||||
.get_vfo = NULL,
|
||||
|
|
149
icom/icom.c
149
icom/icom.c
|
@ -1655,7 +1655,8 @@ static int get_split_vfos(const RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo)
|
|||
{
|
||||
if ((rig->state.vfo_list & (RIG_VFO_A|RIG_VFO_B)) == (RIG_VFO_A|RIG_VFO_B)) {
|
||||
*rx_vfo = RIG_VFO_A;
|
||||
*tx_vfo = RIG_VFO_B;
|
||||
*tx_vfo = RIG_VFO_B; /* rig doesn't enforce this but
|
||||
convention is needed here */
|
||||
} else if ((rig->state.vfo_list & (RIG_VFO_MAIN|RIG_VFO_SUB)) == (RIG_VFO_MAIN|RIG_VFO_SUB)) {
|
||||
*rx_vfo = RIG_VFO_MAIN;
|
||||
*tx_vfo = RIG_VFO_SUB;
|
||||
|
@ -1989,55 +1990,48 @@ int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_wid
|
|||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* icom_set_split_freq_mode
|
||||
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
||||
* icom_set_vfo,icom_set_mode works for this rig
|
||||
* FIXME: status
|
||||
*/
|
||||
int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mode, pbwidth_t tx_width)
|
||||
/* find out what the split VFO, Freq, Mode and Width are.
|
||||
|
||||
Leaves the split VFO as current and returns a current VFO to switch
|
||||
back to. The current VFO may be NONE in which case no switch back is
|
||||
required */
|
||||
static int get_split_status (RIG * rig, vfo_t * curr_vfo,
|
||||
freq_t * split_freq,
|
||||
rmode_t * split_mode,
|
||||
pbwidth_t * split_width)
|
||||
{
|
||||
struct icom_priv_data * priv = (struct icom_priv_data *)rig->state.priv;
|
||||
int status;
|
||||
vfo_t rx_vfo, tx_vfo;
|
||||
|
||||
/* This method works also in memory mode(RIG_VFO_MEM) */
|
||||
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig_set_freq(rig, RIG_VFO_CURR, tx_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* strategy here is to attempt to leave the original VFO selected
|
||||
/* Strategy here is to attempt to leave the original VFO selected
|
||||
even though Icom provides no way to tell what the current VFO is. So
|
||||
we read current frequency and mode and compare with SUB/B, this
|
||||
gives up a clue so long as both VFOs are not the same frequency and
|
||||
mode (and we don't really care if they are, the price for not using
|
||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
||||
rig relays). */
|
||||
rig relays).
|
||||
|
||||
freq_t orig_freq, second_freq;
|
||||
rmode_t orig_mode, second_mode;
|
||||
pbwidth_t orig_width, second_width;
|
||||
There is a further complication in that A/B VFO style Icoms swap
|
||||
VFOs during split Tx but there is no guaranteed way of querying Tx
|
||||
status. In this case we must briefly turn off split to read the Rx
|
||||
VFO details. Even more complex if the VFOs are set the same then
|
||||
only by adjusting one before disabling split can we be sure that we
|
||||
have identified which is which.
|
||||
|
||||
This all relies on some assumptions:- the rig can only be set or
|
||||
reset to and from split mode via this library, when split the Tx
|
||||
status must remain constant through this sequence. */
|
||||
|
||||
int status;
|
||||
struct icom_priv_data * priv = (struct icom_priv_data *)rig->state.priv;
|
||||
vfo_t rx_vfo, tx_vfo;
|
||||
freq_t orig_freq;
|
||||
rmode_t orig_mode;
|
||||
pbwidth_t orig_width;
|
||||
unsigned char ackbuf[MAXFRAMELEN];
|
||||
int ack_len = sizeof(ackbuf);
|
||||
int tx_split = 0;
|
||||
freq_t offset = 0;
|
||||
|
||||
*curr_vfo = RIG_VFO_NONE;
|
||||
|
||||
status = get_split_vfos(rig, &rx_vfo, &tx_vfo);
|
||||
if (status != RIG_OK) return status;
|
||||
|
||||
|
@ -2049,7 +2043,7 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mod
|
|||
|
||||
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)) {
|
||||
/* A/B VFO rigs swap VFO on split Tx so we need to find out if we are in Tx */
|
||||
if (priv->split_on) {
|
||||
if (priv->split_on) { /* broken if user changes split on rig :( */
|
||||
status = icom_transaction (rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len);
|
||||
if (status != RIG_OK) return status;
|
||||
if (ack_len != 1 || ackbuf[0] != ACK) {
|
||||
|
@ -2057,13 +2051,13 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mod
|
|||
"len=%d\n", ackbuf[0],ack_len);
|
||||
return -RIG_ERJCTED;
|
||||
}
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &second_freq);
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, split_freq);
|
||||
if (status != RIG_OK) return status;
|
||||
if (second_freq == orig_freq) {
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &second_mode, &second_width);
|
||||
if (*split_freq == orig_freq) {
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, split_mode, split_width);
|
||||
if (status != RIG_OK) return status;
|
||||
}
|
||||
if (second_freq != orig_freq || second_mode != orig_mode || second_width != orig_width) {
|
||||
if (*split_freq != orig_freq || *split_mode != orig_mode || *split_width != orig_width) {
|
||||
/* definitely split tx as turning off split changed VFO */
|
||||
tx_split = -1;
|
||||
/* restore split state */
|
||||
|
@ -2080,7 +2074,7 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mod
|
|||
status = icom_set_vfo(rig, tx_vfo);
|
||||
if (status != RIG_OK) return status;
|
||||
offset = Hz(10);
|
||||
status = icom_set_freq(rig, RIG_VFO_CURR, second_freq + offset);
|
||||
status = icom_set_freq(rig, RIG_VFO_CURR, *split_freq + offset);
|
||||
if (status != RIG_OK) return status;
|
||||
/* restore split state */
|
||||
status = icom_transaction (rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len);
|
||||
|
@ -2093,7 +2087,7 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mod
|
|||
freq_t temp_freq;
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &temp_freq);
|
||||
if (status != RIG_OK) return status;
|
||||
if (temp_freq != second_freq + offset) {
|
||||
if (temp_freq != *split_freq + offset) {
|
||||
/* frequency changed so we must be in Tx */
|
||||
tx_split = -1;
|
||||
/* VFO B current since split Tx */
|
||||
|
@ -2108,26 +2102,69 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mod
|
|||
if (0 == offset) {
|
||||
status = icom_set_vfo(rig, tx_vfo);
|
||||
if (status != RIG_OK) return status;
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &second_freq);
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, split_freq);
|
||||
if (status != RIG_OK) return status;
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &second_mode, &second_width);
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, split_mode, split_width);
|
||||
if (status != RIG_OK) return status;
|
||||
}
|
||||
}
|
||||
if (!tx_split && (*split_freq != orig_freq
|
||||
|| *split_mode != orig_mode
|
||||
|| *split_width != orig_width
|
||||
|| priv->split_on)) {
|
||||
/* Rx VFO must have been selected when we started so switch back
|
||||
to it. We may be wrong but in that case A & B are the same so
|
||||
it doesn't matter so long as in split Tx is always VFO B */
|
||||
*curr_vfo = rx_vfo;
|
||||
}
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* icom_set_split_freq_mode
|
||||
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
||||
* icom_set_vfo,icom_set_mode works for this rig
|
||||
* FIXME: status
|
||||
*/
|
||||
int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mode, pbwidth_t tx_width)
|
||||
{
|
||||
int status;
|
||||
struct icom_priv_data * priv = (struct icom_priv_data *)rig->state.priv;
|
||||
|
||||
/* This method works also in memory mode(RIG_VFO_MEM) */
|
||||
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
||||
if (status != RIG_OK) return status;
|
||||
|
||||
status = rig_set_freq(rig, RIG_VFO_CURR, tx_freq);
|
||||
if (status != RIG_OK) return status;
|
||||
|
||||
status = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
||||
if (status != RIG_OK) return status;
|
||||
|
||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
||||
if (status != RIG_OK) return status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
vfo_t curr_vfo;
|
||||
freq_t split_freq;
|
||||
rmode_t split_mode;
|
||||
pbwidth_t split_width;
|
||||
status = get_split_status (rig, &curr_vfo, &split_freq,
|
||||
&split_mode, &split_width);
|
||||
if (status != RIG_OK) return status;
|
||||
|
||||
status = rig_set_freq(rig, RIG_VFO_CURR, tx_freq);
|
||||
if (status != RIG_OK) return status;
|
||||
status = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
||||
if (status != RIG_OK) return status;
|
||||
|
||||
if (!tx_split && (second_freq != orig_freq
|
||||
|| second_mode != orig_mode
|
||||
|| second_width != orig_width
|
||||
|| priv->split_on)) {
|
||||
/* Rx VFO must have been selected when we started so switch back
|
||||
to it. We may be wrong but in that case A & B are the same so
|
||||
it doesn't matter so long as changing split Tx is always B */
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
}
|
||||
if (curr_vfo != RIG_VFO_NONE)
|
||||
{
|
||||
status = icom_set_vfo(rig, curr_vfo);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue