Fix Icom rigs to use 0x25 command if capable

Fixes #1 and and #2 in the issue
https://github.com/Hamlib/Hamlib/issues/762
pull/769/head
Mike Black W9MDB 2021-08-13 07:42:39 -05:00
rodzic ad43cd793a
commit 014bc04ddf
3 zmienionych plików z 184 dodań i 38 usunięć

Wyświetl plik

@ -902,6 +902,7 @@ static int icom_set_default_vfo(RIG *rig)
{
rig_debug(RIG_DEBUG_TRACE, "%s: setting default as MAIN/VFOA\n",
__func__);
TRACE;
retval = rig_set_vfo(rig, RIG_VFO_MAIN); // we'll default to Main in this case
if (retval != RIG_OK)
@ -925,6 +926,7 @@ static int icom_set_default_vfo(RIG *rig)
{
rig_debug(RIG_DEBUG_TRACE, "%s: setting default as MAIN\n",
__func__);
TRACE;
retval = rig_set_vfo(rig, RIG_VFO_MAIN); // we'll default to Main in this case
rig->state.current_vfo = RIG_VFO_MAIN;
}
@ -932,9 +934,14 @@ static int icom_set_default_vfo(RIG *rig)
{
rig_debug(RIG_DEBUG_TRACE, "%s: setting default as VFOA\n",
__func__);
TRACE;
retval = RIG_OK;
if (rig->state.current_vfo != RIG_VFO_A)
{
retval = rig_set_vfo(rig,
RIG_VFO_A); // we'll default to VFOA for all others
rig->state.current_vfo = RIG_VFO_A;
}
}
else
{
@ -1009,7 +1016,7 @@ int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
rs = &rig->state;
priv = (struct icom_priv_data *) rs->priv;
if (rig->state.current_vfo == RIG_VFO_NONE && vfo == RIG_VFO_CURR)
if (rig->state.current_vfo == RIG_VFO_NONE)
{
icom_set_default_vfo(rig);
}
@ -1021,16 +1028,20 @@ int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
rig_strvfo(vfo));
}
rig_debug(RIG_DEBUG_TRACE, "%s: set_vfo_curr=%s\n", __func__,
rig_strvfo(rig->state.current_vfo));
retval = set_vfo_curr(rig, vfo, rig->state.current_vfo);
if (retval != RIG_OK)
if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ))
{
RETURNFUNC(retval);
TRACE;
rig_debug(RIG_DEBUG_TRACE, "%s: set_vfo_curr=%s\n", __func__,
rig_strvfo(rig->state.current_vfo));
retval = set_vfo_curr(rig, vfo, rig->state.current_vfo);
if (retval != RIG_OK)
{
RETURNFUNC(retval);
}
}
retval = rig_get_freq(rig, RIG_VFO_CURR, &curr_freq);
retval = rig_get_freq(rig, vfo, &curr_freq);
if (retval != RIG_OK)
{
@ -1043,10 +1054,37 @@ int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
*/
to_bcd(freqbuf, freq, freq_len * 2);
cmd = C_SET_FREQ;
subcmd = -1;
retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf,
// mike
if (rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ)
{
vfo_t vfo_unselected = RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B;
// if we are on the "other" vfo already then we have to allow for that
if (rig->state.current_vfo & vfo_unselected)
{
TRACE;
vfo_unselected = RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_SUB_A | RIG_VFO_MAIN_A;
}
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): vfo=%s, currvfo=%s\n", __func__, __LINE__, rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo));
subcmd = 0x00;
// if we ask for unselected but we're not on unselected subcmd2 changes
if ((vfo & vfo_unselected) && !(rig->state.current_vfo & vfo_unselected))
{
TRACE;
subcmd = 0x01; // get unselected VFO
}
cmd = 0x25;
retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf,
&ack_len);
}
else
{
cmd = C_SET_FREQ;
subcmd = -1;
retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf,
&ack_len);
}
hl_usleep(50 * 1000); // pause for transceive message and we'll flush it
if (retval != RIG_OK)
@ -1677,6 +1715,48 @@ int icom_set_dsp_flt(RIG *rig, rmode_t mode, pbwidth_t width)
RETURNFUNC(RIG_OK);
}
static int icom_set_mode_x26(RIG *rig, vfo_t vfo, rmode_t mode, int datamode, int filter)
{
struct icom_priv_data *priv = rig->state.priv;
int retval;
unsigned char buf[3];
ENTERFUNC;
if (priv->x26cmdfails) RETURNFUNC(-RIG_ENAVAIL);
int cmd2 = 0x26;
int subcmd2 = 0x00;
vfo_t vfo_unselected = RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B;
// if we are on the "other" vfo already then we have to allow for that
if (rig->state.current_vfo & vfo_unselected)
{
vfo_unselected = RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_SUB_A | RIG_VFO_MAIN_A;
}
// if we ask for unselected but we're not on unselected subcmd2 changes
if ((vfo & vfo_unselected) && !(rig->state.current_vfo & vfo_unselected))
{
subcmd2 = 0x01; // get unselected VFO
}
buf[0] = mode;
buf[1] = datamode;
// filter fixed to filter 1 due to IC7300 bug defaulting to filter 2 on mode changed -- yuck!!
// buf[2] = filter // if Icom ever fixed this
buf[2] = 1;
retval = icom_transaction(rig, cmd2, subcmd2, buf, 3, NULL, NULL);
if (retval != RIG_OK)
{
priv->x26cmdfails = 1;
rig_debug(RIG_DEBUG_WARN,
"%s: rig does not support 0x26 CI-V cmd\n", __func__);
return -RIG_ENAVAIL;
}
RETURNFUNC(RIG_OK);
}
/*
* icom_set_mode_with_data
*/
@ -1687,6 +1767,7 @@ int icom_set_mode_with_data(RIG *rig, vfo_t vfo, rmode_t mode,
unsigned char ackbuf[MAXFRAMELEN];
int ack_len = sizeof(ackbuf);
rmode_t icom_mode;
//struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv;
unsigned char dm_sub_cmd =
rig->caps->rig_model == RIG_MODEL_IC7200 ? 0x04 : S_MEM_DATA_MODE;
int filter_byte = rig->caps->rig_model == RIG_MODEL_IC7100
@ -1728,8 +1809,8 @@ int icom_set_mode_with_data(RIG *rig, vfo_t vfo, rmode_t mode,
break;
}
rig_debug(RIG_DEBUG_VERBOSE, "%s mode=%d, width=%d\n", __func__, (int)icom_mode,
(int)width);
rig_debug(RIG_DEBUG_VERBOSE, "%s mode=%d, width=%d, curr_vfo=%s\n", __func__, (int)icom_mode,
(int)width, rig_strvfo(rig->state.current_vfo));
retval = icom_set_mode(rig, vfo, icom_mode, width);
hl_usleep(50 * 1000); // pause for possible transceive message which we'll flush
@ -1739,21 +1820,21 @@ int icom_set_mode_with_data(RIG *rig, vfo_t vfo, rmode_t mode,
unsigned char datamode[2];
unsigned char mode_icom; // Not used, we only need the width
signed char width_icom;
TRACE;
switch (mode)
{
case RIG_MODE_PKTUSB:
case RIG_MODE_PKTLSB:
case RIG_MODE_PKTFM:
case RIG_MODE_PKTAM:
/* some rigs (e.g. IC-7700 & IC-7800)
have D1/2/3 but we cannot know
which to set so just set D1 */
datamode[0] = 0x01;
datamode[1] = 0x01; // default to filter 1
break;
default:
datamode[0] = 0x00;
datamode[1] = 0x01; // default to filter 1
break;
}
@ -1761,13 +1842,20 @@ int icom_set_mode_with_data(RIG *rig, vfo_t vfo, rmode_t mode,
if (filter_byte) // then we need the filter width byte too
{
if (width_icom == -1) datamode[1] = 1; // default to filter 1
else datamode[1] = width_icom;
retval =
TRACE;
if (datamode[0] == 0) datamode[1]=0; // the only good combo possible according to manual
rig_debug(RIG_DEBUG_TRACE, "%s(%d) mode_icom=%d, datamode[0]=%d, filter=%d\n", __func__, __LINE__, mode_icom, datamode[0], datamode[1]);
retval = icom_set_mode_x26(rig, vfo, mode_icom, datamode[0], datamode[1]);
if (retval != RIG_OK)
{
retval =
icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, datamode, 2, ackbuf, &ack_len);
}
}
else
{
TRACE;
retval =
icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, datamode, 1, ackbuf, &ack_len);
}
@ -1805,9 +1893,10 @@ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
unsigned char icmode;
signed char icmode_ext;
int ack_len = sizeof(ackbuf), retval, err;
int swapvfos = 0;
rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, mode=%s, width=%d\n", __func__,
rig_strvfo(vfo), rig_strrmode(mode), (int)width);
rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, mode=%s, width=%d, current_vfo=%s\n", __func__,
rig_strvfo(vfo), rig_strrmode(mode), (int)width, rig_strvfo(rig->state.current_vfo));
rs = &rig->state;
priv = (struct icom_priv_data *) rs->priv;
@ -1845,12 +1934,28 @@ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
icmode_ext = -1;
}
// some Icom rigs have seperate modes for VFOB/Sub
// switching to VFOB should not matter for the other rigs
// This needs to be improved for RIG_TARGETABLE_MODE rigs
if ((vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) && ((rig->state.current_vfo == RIG_VFO_A || rig->state.current_vfo == RIG_VFO_MAIN) || rig->state.current_vfo == RIG_VFO_CURR))
{
TRACE;
swapvfos = 1;
rig_set_vfo(rig,RIG_VFO_B);
}
rig_debug(RIG_DEBUG_VERBOSE, "%s: #2 icmode=%d, icmode_ext=%d\n", __func__,
icmode, icmode_ext);
retval = icom_transaction(rig, C_SET_MODE, icmode,
(unsigned char *) &icmode_ext,
(icmode_ext == -1 ? 0 : 1), ackbuf, &ack_len);
if (swapvfos)
{
TRACE;
rig_set_vfo(rig,RIG_VFO_A);
}
if (retval != RIG_OK)
{
RETURNFUNC(retval);
@ -2125,6 +2230,7 @@ int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
{
rig_debug(RIG_DEBUG_TRACE, "%s(%d): forcing default VFO_A\n", __func__,
__LINE__);
TRACE;
rig_set_vfo(rig, RIG_VFO_A); // force VFOA
}
@ -2147,8 +2253,10 @@ int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
if (vfosave != vfo)
{
// right now forcing VFOA/B arrangement -- reverse not supported yet
TRACE;
rig_set_vfo(rig, RIG_VFO_B);
// If VFOB width is ever different than VFOA
// we need to figure out how to read VFOB without swapping VFOs
//TRACE;
//rig_set_vfo(rig, RIG_VFO_B);
retval = icom_get_dsp_flt(rig, *mode);
*width = retval;
@ -2159,7 +2267,8 @@ int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
rig->state.cache.widthMainB = retval;
rig_debug(RIG_DEBUG_TRACE, "%s(%d): vfosave=%s, currvfo=%s\n", __func__,
__LINE__, rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo));
rig_set_vfo(rig, RIG_VFO_A);
//TRACE;
//rig_set_vfo(rig, RIG_VFO_A);
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s returning mode=%s, width=%d\n", __func__,
rig_strvfo(vfo), rig_strrmode(*mode), (int)*width);
}
@ -4897,7 +5006,8 @@ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
rig_debug(RIG_DEBUG_TRACE, "%s: rx_vfo=%s, tx_vfo=%s\n", __func__,
rig_strvfo(rx_vfo), rig_strvfo(tx_vfo));
if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo)))
TRACE;
if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo)))
{
RETURNFUNC(retval);
}
@ -4915,13 +5025,15 @@ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
__func__,
priv->split_on, rig_strvfo(rx_vfo));
if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
TRACE;
if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) && RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
{
RETURNFUNC(retval);
}
}
else if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
{
TRACE;
RETURNFUNC(retval);
}
@ -5138,6 +5250,7 @@ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
rig_debug(RIG_DEBUG_TRACE, "%s: SATMODE rig so returning vfo to %s\n", __func__,
rig_strvfo(rx_vfo));
TRACE;
if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
{
RETURNFUNC(retval);
@ -5145,6 +5258,7 @@ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
}
else if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
{
TRACE;
RETURNFUNC(retval);
}
@ -5254,7 +5368,8 @@ int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode,
RETURNFUNC(retval);
}
if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
TRACE;
if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
{
RETURNFUNC(retval);
}
@ -5365,6 +5480,7 @@ int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode,
RETURNFUNC(retval);
}
TRACE;
if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
{
RETURNFUNC(retval);
@ -5515,6 +5631,7 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq,
RETURNFUNC(retval);
}
TRACE;
if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo)))
{
RETURNFUNC(retval);
@ -5526,6 +5643,7 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq,
RETURNFUNC(retval);
}
TRACE;
if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
{
RETURNFUNC(retval);
@ -5647,6 +5765,7 @@ int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq,
RETURNFUNC(retval);
}
TRACE;
if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo)))
{
RETURNFUNC(retval);
@ -8567,6 +8686,7 @@ static int set_vfo_curr(RIG *rig, vfo_t vfo, vfo_t curr_vfo)
{
rig_debug(RIG_DEBUG_TRACE, "%s: setting new vfo=%s\n", __func__,
rig_strvfo(vfo));
TRACE;
retval = rig_set_vfo(rig, vfo);
if (retval != RIG_OK)

Wyświetl plik

@ -30,7 +30,7 @@
#include <sys/time.h>
#endif
#define BACKEND_VER "20210801"
#define BACKEND_VER "20210812"
#define ICOM_IS_SECONDARY_VFO(vfo) ((vfo) & (RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B))
#define ICOM_GET_VFO_NUMBER(vfo) (ICOM_IS_SECONDARY_VFO(vfo) ? 0x01 : 0x00)
@ -258,6 +258,7 @@ struct icom_priv_data
freq_t vfoa_freq; /*!< Track last setting of vfoa -- used to return last freq when ptt is asserted */
freq_t vfob_freq; /*!< Track last setting of vfob -- used to return last freq when ptt is asserted */
int x25cmdfails; /*!< This will get set if the 0x25 command fails so we try just once */
int x26cmdfails; /*!< This will get set if the 0x26 command fails so we try just once */
int x1cx03cmdfails; /*!< This will get set if the 0x1c 0x03 command fails so we try just once */
int poweron; /*!< To prevent powering on more than once */
unsigned char filter; /*!< Current filter selected */

Wyświetl plik

@ -1036,10 +1036,11 @@ int HAMLIB_API rig_open(RIG *rig)
}
else // vfo fails so set some sensible defaults
{
int backend_num = RIG_BACKEND_NUM(rig->caps->rig_model);
//int backend_num = RIG_BACKEND_NUM(rig->caps->rig_model);
rs->tx_vfo = RIG_VFO_TX;
rs->current_vfo = RIG_VFO_CURR;
#if 0 // done in the back end
if (backend_num == RIG_ICOM)
{
TRACE;
@ -1047,7 +1048,8 @@ int HAMLIB_API rig_open(RIG *rig)
rig_debug(RIG_DEBUG_TRACE, "%s: Icom rig so default vfo = %s\n", __func__,
rig_strvfo(rs->current_vfo));
}
else if (rig->caps->set_vfo == NULL)
#endif
if (rig->caps->set_vfo == NULL)
{
// for non-Icom rigs if there's no set_vfo then we need to set one
rs->current_vfo = vfo_fixup(rig, RIG_VFO_A, rig->state.cache.split);
@ -2587,14 +2589,23 @@ pbwidth_t HAMLIB_API rig_passband_wide(RIG *rig, rmode_t mode)
*
* \sa rig_get_vfo()
*/
#if BUILTINFUNC
#undef rig_set_vfo
int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo, const char *func)
#else
int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo)
#endif
{
const struct rig_caps *caps;
int retcode;
freq_t curr_freq;
ENTERFUNC;
#if BUILTINFUNC
rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, called from %s\n", __func__, rig_strvfo(vfo),func);
#else
rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo));
#endif
if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB)
{
@ -2647,7 +2658,7 @@ int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo)
TRACE;
vfo_t vfo_save = rig->state.current_vfo;
rig->state.current_vfo = vfo;
if (vfo != RIG_VFO_CURR) rig->state.current_vfo = vfo;
retcode = caps->set_vfo(rig, vfo);
if (retcode == RIG_OK)
@ -3782,7 +3793,9 @@ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
if (caps->set_vfo)
{
TRACE;
retcode = caps->set_vfo(rig, tx_vfo);
retcode = RIG_OK;
if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ))
retcode = caps->set_vfo(rig, tx_vfo);
}
else if (rig_has_vfo_op(rig, RIG_OP_TOGGLE) && caps->vfo_op)
{
@ -3825,7 +3838,9 @@ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
if (caps->set_vfo)
{
TRACE;
rc2 = caps->set_vfo(rig, curr_vfo);
rc2 = RIG_OK;
if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ))
rc2 = caps->set_vfo(rig, curr_vfo);
}
else
{
@ -4439,7 +4454,7 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
RETURNFUNC(-RIG_ENAVAIL);
}
vfo = vfo_fixup(rig, vfo, split);
vfo = vfo_fixup(rig, tx_vfo, split);
if (vfo != RIG_VFO_A && vfo != RIG_VFO_B)
{
@ -4447,7 +4462,12 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
}
// set rig to the the requested RX VFO
TRACE;
rig_set_vfo(rig, vfo == RIG_VFO_B?RIG_VFO_B:RIG_VFO_A);
if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ))
#if BUILTINFUNC
rig_set_vfo(rig, vfo == RIG_VFO_B?RIG_VFO_B:RIG_VFO_A, __builtin_FUNCTION());
#else
rig_set_vfo(rig, vfo == RIG_VFO_B?RIG_VFO_B:RIG_VFO_A);
#endif
if (vfo == RIG_VFO_CURR
|| vfo == rig->state.current_vfo)
@ -4473,24 +4493,29 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
curr_vfo = rig->state.current_vfo;
TRACE;
retcode = caps->set_vfo(rig, vfo);
if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ))
{
retcode = caps->set_vfo(rig, vfo);
if (retcode != RIG_OK)
{
RETURNFUNC(retcode);
}
}
TRACE;
retcode = caps->set_split_vfo(rig, vfo, split, tx_vfo);
/* try and revert even if we had an error above */
rc2 = caps->set_vfo(rig, curr_vfo);
if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) {
rc2 = caps->set_vfo(rig, curr_vfo);
if (RIG_OK == retcode)
{
/* return the first error code */
retcode = rc2;
}
}
if (retcode == RIG_OK)
{