kopia lustrzana https://github.com/Hamlib/Hamlib
Simplify/streamline split VFO handling, especially in the Icom backend. Detect reverse split automatically at startup for Icom rigs.
rodzic
4a926ec503
commit
e2e723ec60
335
rigs/icom/icom.c
335
rigs/icom/icom.c
|
@ -1108,24 +1108,8 @@ retry_open:
|
|||
|
||||
if (rig->caps->has_get_func & RIG_FUNC_SATMODE)
|
||||
{
|
||||
// retval is important here -- used below
|
||||
retval = rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode);
|
||||
|
||||
// RIG_OK return means this rig has satmode capability and Main/Sub VFOs
|
||||
// Should we also set/force VFOA for Main&Sub here?
|
||||
if (retval == RIG_OK)
|
||||
{
|
||||
if (satmode)
|
||||
{
|
||||
rig->state.rx_vfo = RIG_VFO_MAIN;
|
||||
rig->state.tx_vfo = RIG_VFO_SUB;
|
||||
}
|
||||
else
|
||||
{
|
||||
rig->state.rx_vfo = RIG_VFO_MAIN;
|
||||
rig->state.tx_vfo = RIG_VFO_MAIN;
|
||||
}
|
||||
}
|
||||
// Getting satmode state updates RX/TX VFOs internally
|
||||
rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode);
|
||||
}
|
||||
|
||||
#if 0 // do not do this here -- needs to be done when ranges are requested instead as this is very slow
|
||||
|
@ -1431,7 +1415,7 @@ int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
|||
retval = icom_set_freq_x25(rig, vfo, freq, freq_len, freqbuf);
|
||||
}
|
||||
|
||||
if (retval == -RIG_ENAVAIL)
|
||||
if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || retval == -RIG_ENAVAIL)
|
||||
{
|
||||
cmd = C_SET_FREQ;
|
||||
subcmd = -1;
|
||||
|
@ -2206,7 +2190,7 @@ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
|||
// It is only necessary to change base mode if command 0x26 is not supported
|
||||
if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE))
|
||||
{
|
||||
retval = icom_set_mode(rig, vfo, base_mode, width);
|
||||
retval = icom_set_mode_without_data(rig, vfo, base_mode, width);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5095,15 +5079,29 @@ int icom_get_split_vfos(RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo)
|
|||
|
||||
rs = (struct rig_state *) &rig->state;
|
||||
|
||||
// Initialize TX VFO if not done yet
|
||||
if (rs->tx_vfo == RIG_VFO_NONE || rs->tx_vfo == RIG_VFO_CURR || rs->tx_vfo == RIG_VFO_TX)
|
||||
{
|
||||
if (rs->cache.split == RIG_SPLIT_OFF)
|
||||
{
|
||||
rs->tx_vfo = rs->current_vfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs->tx_vfo = vfo_fixup(rig, RIG_VFO_OTHER, rs->cache.split);
|
||||
}
|
||||
}
|
||||
|
||||
if (VFO_HAS_A_B_ONLY)
|
||||
{
|
||||
*rx_vfo = *tx_vfo = RIG_VFO_A;
|
||||
|
||||
if (rs->cache.split != RIG_SPLIT_OFF)
|
||||
if (rs->cache.split == RIG_SPLIT_OFF)
|
||||
{
|
||||
*rx_vfo = RIG_VFO_A;
|
||||
*tx_vfo = RIG_VFO_B; /* rig doesn't enforce this but
|
||||
convention is needed here */
|
||||
*rx_vfo = *tx_vfo = rs->current_vfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
*rx_vfo = rs->current_vfo;
|
||||
*tx_vfo = rs->tx_vfo;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: VFO_HAS_A_B_ONLY, split=%d, rx=%s, tx=%s\n",
|
||||
|
@ -5111,12 +5109,14 @@ int icom_get_split_vfos(RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo)
|
|||
}
|
||||
else if (VFO_HAS_MAIN_SUB_ONLY)
|
||||
{
|
||||
*rx_vfo = *tx_vfo = RIG_VFO_MAIN;
|
||||
|
||||
if (rs->cache.split != RIG_SPLIT_OFF)
|
||||
if (rs->cache.split == RIG_SPLIT_OFF)
|
||||
{
|
||||
*rx_vfo = RIG_VFO_MAIN;
|
||||
*tx_vfo = RIG_VFO_SUB;
|
||||
*rx_vfo = *tx_vfo = rs->current_vfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
*rx_vfo = rs->current_vfo;
|
||||
*tx_vfo = rs->tx_vfo;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE,
|
||||
|
@ -5127,7 +5127,7 @@ int icom_get_split_vfos(RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo)
|
|||
{
|
||||
int satmode = 0;
|
||||
|
||||
// e.g. IC9700 split on Main/Sub does not work
|
||||
// e.g. IC-9700 split on Main/Sub does not work
|
||||
// only Main VFOA/B and SubRx/MainTx split works
|
||||
if (rig->caps->has_get_func & RIG_FUNC_SATMODE)
|
||||
{
|
||||
|
@ -5137,18 +5137,17 @@ int icom_get_split_vfos(RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo)
|
|||
// don't care about retval here, only care about satmode=1
|
||||
if (satmode)
|
||||
{
|
||||
*rx_vfo = rs->rx_vfo = RIG_VFO_MAIN;
|
||||
*tx_vfo = rs->tx_vfo = RIG_VFO_SUB;
|
||||
*rx_vfo = RIG_VFO_MAIN;
|
||||
*tx_vfo = RIG_VFO_SUB;
|
||||
}
|
||||
else if (rs->cache.split != RIG_SPLIT_OFF)
|
||||
else if (rs->cache.split == RIG_SPLIT_OFF)
|
||||
{
|
||||
*rx_vfo = rs->rx_vfo = RIG_VFO_A;
|
||||
*tx_vfo = rs->tx_vfo = RIG_VFO_B;
|
||||
*rx_vfo = *tx_vfo = rs->current_vfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
*rx_vfo = rs->rx_vfo = RIG_VFO_A;
|
||||
*tx_vfo = rs->tx_vfo = RIG_VFO_A;
|
||||
*rx_vfo = rs->current_vfo;
|
||||
*tx_vfo = rs->tx_vfo;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE,
|
||||
|
@ -5157,7 +5156,7 @@ int icom_get_split_vfos(RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo)
|
|||
}
|
||||
else
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid vfo setup?\n", __func__);
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: unknown VFO setup\n", __func__);
|
||||
RETURNFUNC(-RIG_ENAVAIL);
|
||||
}
|
||||
|
||||
|
@ -5265,10 +5264,6 @@ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
|
|||
RETURNFUNC2(retval);
|
||||
}
|
||||
|
||||
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||
assumptions allow us to deal with the lack of VFO and split
|
||||
queries */
|
||||
/* broken if user changes split on rig :( */
|
||||
if (VFO_HAS_A_B_ONLY && rs->cache.split != RIG_SPLIT_OFF)
|
||||
{
|
||||
|
@ -5461,10 +5456,6 @@ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
|
|||
RETURNFUNC2(retval);
|
||||
}
|
||||
|
||||
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||
assumptions allow us to deal with the lack of VFO and split
|
||||
queries */
|
||||
/* broken if user changes split on rig :( */
|
||||
if (VFO_HAS_A_B_ONLY && rs->cache.split != RIG_SPLIT_OFF)
|
||||
{
|
||||
|
@ -5577,10 +5568,6 @@ int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode,
|
|||
RETURNFUNC(retval);
|
||||
}
|
||||
|
||||
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||
assumptions allow us to deal with the lack of VFO and split
|
||||
queries */
|
||||
/* broken if user changes split on rig :( */
|
||||
if (VFO_HAS_A_B_ONLY && rs->cache.split != RIG_SPLIT_OFF)
|
||||
{
|
||||
|
@ -5683,10 +5670,6 @@ int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode,
|
|||
RETURNFUNC(retval);
|
||||
}
|
||||
|
||||
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||
assumptions allow us to deal with the lack of VFO and split
|
||||
queries */
|
||||
/* broken if user changes split on rig :( */
|
||||
if (VFO_HAS_A_B_ONLY && rs->cache.split != RIG_SPLIT_OFF)
|
||||
{
|
||||
|
@ -5812,10 +5795,6 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq,
|
|||
RETURNFUNC2(retval);
|
||||
}
|
||||
|
||||
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||
assumptions allow us to deal with the lack of VFO and split
|
||||
queries */
|
||||
/* broken if user changes split on rig :( */
|
||||
if (VFO_HAS_A_B && (split_assumed || rs->cache.split != RIG_SPLIT_OFF))
|
||||
{
|
||||
|
@ -5970,10 +5949,6 @@ int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq,
|
|||
RETURNFUNC(retval);
|
||||
}
|
||||
|
||||
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||
assumptions allow us to deal with the lack of VFO and split
|
||||
queries */
|
||||
/* broken if user changes split on rig :( */
|
||||
if (VFO_HAS_A_B_ONLY && rs->cache.split != RIG_SPLIT_OFF)
|
||||
{
|
||||
|
@ -6038,7 +6013,7 @@ int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq,
|
|||
* icom_set_split
|
||||
* Assumes rig!=NULL, rig->state.priv!=NULL
|
||||
*/
|
||||
int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
|
||||
int icom_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo)
|
||||
{
|
||||
struct rig_state *rs = &rig->state;
|
||||
const struct icom_priv_caps *priv_caps = rig->caps->priv;
|
||||
|
@ -6053,171 +6028,63 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
|
|||
* S Sub 1 Main -- RX on Sub, TX on Main
|
||||
*/
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"%s called vfo='%s', split=%d, tx_vfo=%s, curr_vfo=%s\n", __func__,
|
||||
rig_strvfo(vfo), split, rig_strvfo(tx_vfo), rig_strvfo(rig->state.current_vfo));
|
||||
"%s called rx_vfo='%s', split=%d, tx_vfo=%s, curr_vfo=%s\n", __func__,
|
||||
rig_strvfo(rx_vfo), split, rig_strvfo(tx_vfo), rig_strvfo(rig->state.current_vfo));
|
||||
|
||||
// This should automatically switch between satmode on/off based on the requested split vfo
|
||||
// This should automatically switch between satmode on/off based on the requested split rx_vfo
|
||||
if (rig->caps->has_get_func & RIG_FUNC_SATMODE)
|
||||
{
|
||||
if ((tx_vfo == RIG_VFO_SUB || tx_vfo == RIG_VFO_MAIN)
|
||||
int satmode = 0;
|
||||
// Check SATMODE status, because it affects commands related to split
|
||||
rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode);
|
||||
|
||||
if ((tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB)
|
||||
&& !rig->state.cache.satmode)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"%s: VFO_SUB and satmode is off so turning satmode on\n",
|
||||
"%s: requesting split for Main/Sub VFO and satmode is OFF so turning satmode ON\n",
|
||||
__func__);
|
||||
rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, 1);
|
||||
rs->tx_vfo = RIG_VFO_SUB;
|
||||
retval = rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, 1);
|
||||
// Split cannot be turned on in satmode, so return after enabling satmode
|
||||
RETURNFUNC2(retval);
|
||||
}
|
||||
else if ((tx_vfo == RIG_VFO_A || tx_vfo == RIG_VFO_B)
|
||||
&& rig->state.cache.satmode)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"%s: VFO_B and satmode is on so turning satmode off\n",
|
||||
"%s: requesting split for VFO A/B and satmode is ON so turning satmode OFF\n",
|
||||
__func__);
|
||||
rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, 0);
|
||||
rs->tx_vfo = RIG_VFO_B;
|
||||
}
|
||||
else if (tx_vfo == RIG_VFO_SUB && rig->state.cache.satmode && split == 1)
|
||||
else if ((tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB) && rig->state.cache.satmode && split == RIG_SPLIT_ON)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"%s: rig in satmode so setting split on is redundant and will create error...returning OK\n",
|
||||
"%s: requesting split for Main/Sub VFO and rig is already in satmode so setting split on "
|
||||
"is redundant and will result in an error, returning OK\n",
|
||||
__func__);
|
||||
// we'll return OK anyways as this is a split mode
|
||||
// and gpredict wants to see the OK response here
|
||||
RETURNFUNC2(RIG_OK); // we'll return OK anyways as this is a split mode
|
||||
// Return OK as satmode is a split mode and gpredict wants to see the OK response here
|
||||
RETURNFUNC2(RIG_OK);
|
||||
}
|
||||
}
|
||||
|
||||
if (rs->current_vfo != rx_vfo && rx_vfo != RIG_VFO_CURR)
|
||||
{
|
||||
// Icom split command requires switching to the RX VFO first
|
||||
retval = rig_set_vfo(rig, rx_vfo);
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
RETURNFUNC2(retval);
|
||||
}
|
||||
}
|
||||
|
||||
switch (split)
|
||||
{
|
||||
case RIG_SPLIT_OFF:
|
||||
|
||||
// if either VFOA or B is the vfo we set to VFOA when split is turned off
|
||||
if (tx_vfo == RIG_VFO_A || tx_vfo == RIG_VFO_B)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s\n", __func__,
|
||||
rig_strvfo(tx_vfo));
|
||||
rs->tx_vfo = RIG_VFO_A;
|
||||
}
|
||||
// otherwise if Main or Sub we set Main or VFOA as the current vfo
|
||||
else if (tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: vfo is VFO_MAIN/SUB tx_vfo=%s\n",
|
||||
__func__, rig_strvfo(tx_vfo));
|
||||
|
||||
if (VFO_HAS_A_B_ONLY)
|
||||
{
|
||||
rs->tx_vfo = RIG_VFO_A;
|
||||
rs->rx_vfo = RIG_VFO_A;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs->tx_vfo = RIG_VFO_MAIN;
|
||||
rs->rx_vfo = RIG_VFO_MAIN;
|
||||
}
|
||||
}
|
||||
|
||||
split_sc = S_SPLT_OFF;
|
||||
break;
|
||||
|
||||
case RIG_SPLIT_ON:
|
||||
split_sc = S_SPLT_ON;
|
||||
rig_debug(RIG_DEBUG_TRACE, "trace %s(%d)\n", __func__, __LINE__);
|
||||
|
||||
// the VFO adjusting here could probably be done in rig.c for all rigs
|
||||
/* If asking for Sub or Main on rig that doesn't have it map it */
|
||||
if (VFO_HAS_A_B_ONLY && ((tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB)
|
||||
|| vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB))
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: vfo clause 1\n", __func__);
|
||||
|
||||
if (tx_vfo == RIG_VFO_MAIN) { tx_vfo = RIG_VFO_A; vfo = RIG_VFO_B; }
|
||||
else if (tx_vfo == RIG_VFO_SUB) { tx_vfo = RIG_VFO_B; vfo = RIG_VFO_A; }
|
||||
|
||||
rs->tx_vfo = tx_vfo;
|
||||
rs->rx_vfo = vfo;
|
||||
}
|
||||
|
||||
/* ensure VFO A is Rx and VFO B is Tx as we assume that elsewhere */
|
||||
else if (VFO_HAS_A_B && (tx_vfo == RIG_VFO_A || tx_vfo == RIG_VFO_B))
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: vfo clause 2\n", __func__);
|
||||
rig_debug(RIG_DEBUG_TRACE,
|
||||
"%s: rx_vfo to VFO_A, tx_vfo to VFO_B because tx_vfo=%s\n", __func__,
|
||||
rig_strvfo(tx_vfo));
|
||||
|
||||
if (tx_vfo == RIG_VFO_B)
|
||||
{
|
||||
rs->tx_vfo = RIG_VFO_B;
|
||||
rs->rx_vfo = vfo = RIG_VFO_A;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs->tx_vfo = RIG_VFO_A;
|
||||
rs->rx_vfo = vfo = RIG_VFO_B;
|
||||
}
|
||||
}
|
||||
else if (VFO_HAS_MAIN_SUB_A_B_ONLY && (tx_vfo == RIG_VFO_MAIN
|
||||
|| tx_vfo == RIG_VFO_SUB))
|
||||
{
|
||||
// do we need another case for tx_vfo = A/B ?
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: vfo clause 3\n", __func__);
|
||||
// if we're asking for split in this case we split Main on A/B
|
||||
rs->tx_vfo = RIG_VFO_SUB;
|
||||
rs->rx_vfo = RIG_VFO_MAIN;
|
||||
rig_debug(RIG_DEBUG_TRACE,
|
||||
"%s: tx=%s, rx=%s because tx_vfo=%s\n", __func__,
|
||||
rig_strvfo(rs->tx_vfo), rig_strvfo(rs->rx_vfo), rig_strvfo(tx_vfo));
|
||||
tx_vfo = RIG_VFO_SUB;
|
||||
|
||||
#if 0 // is this needed for satmode?
|
||||
|
||||
// make sure we're on Main/VFOA
|
||||
HAMLIB_TRACE;
|
||||
|
||||
if (RIG_OK != (retval = icom_set_vfo(rig, RIG_VFO_MAIN)))
|
||||
{
|
||||
RETURNFUNC2(retval);
|
||||
}
|
||||
|
||||
HAMLIB_TRACE;
|
||||
|
||||
if (RIG_OK != (retval = icom_set_vfo(rig, RIG_VFO_A)))
|
||||
{
|
||||
RETURNFUNC2(retval);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
else if (VFO_HAS_MAIN_SUB && (tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB))
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: vfo clause 4\n", __func__);
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: set_vfo because tx_vfo=%s\n", __func__,
|
||||
rig_strvfo(tx_vfo));
|
||||
|
||||
#if 0 // do we need this for satmode?
|
||||
|
||||
HAMLIB_TRACE;
|
||||
|
||||
if (RIG_OK != (retval = icom_set_vfo(rig, tx_vfo)))
|
||||
{
|
||||
RETURNFUNC2(retval);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
rs->rx_vfo = vfo;
|
||||
rs->tx_vfo = tx_vfo;
|
||||
|
||||
split_sc = S_SPLT_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: split on vfo=%s not known\n", __func__,
|
||||
rig_strvfo(vfo));
|
||||
RETURNFUNC2(-RIG_EINVAL);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -6229,22 +6096,22 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
|
|||
{
|
||||
int wvfo = (tx_vfo & (RIG_VFO_A | RIG_VFO_MAIN)) ? S_SUB : S_MAIN;
|
||||
|
||||
if (RIG_OK != (retval = icom_set_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH,
|
||||
split_sc)))
|
||||
retval = icom_set_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, split_sc);
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
RETURNFUNC2(retval);
|
||||
}
|
||||
|
||||
if (RIG_OK != (retval = icom_transaction(rig, C_SET_VFO, wvfo, NULL, 0,
|
||||
ackbuf, &ack_len)))
|
||||
retval = icom_transaction(rig, C_SET_VFO, wvfo, NULL, 0, ackbuf, &ack_len);
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
RETURNFUNC2(retval);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RIG_OK != (retval = icom_transaction(rig, C_CTL_SPLT, split_sc, NULL, 0,
|
||||
ackbuf, &ack_len)))
|
||||
retval = icom_transaction(rig, C_CTL_SPLT, split_sc, NULL, 0, ackbuf, &ack_len);
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
RETURNFUNC2(retval);
|
||||
}
|
||||
|
@ -6255,13 +6122,10 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
|
|||
RETURNFUNC2(retval);
|
||||
}
|
||||
|
||||
rs->cache.split = split;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"%s: vfo=%s curr_vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n",
|
||||
__func__, rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo),
|
||||
rig_strvfo(rs->rx_vfo),
|
||||
rig_strvfo(rs->tx_vfo), split);
|
||||
"%s: curr_vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n",
|
||||
__func__, rig_strvfo(rig->state.current_vfo),
|
||||
rig_strvfo(rx_vfo), rig_strvfo(tx_vfo), split);
|
||||
|
||||
RETURNFUNC2(RIG_OK);
|
||||
}
|
||||
|
@ -6273,7 +6137,7 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
|
|||
* Does not appear to be supported by any mode?
|
||||
* \sa icom_mem_get_split_vfo()
|
||||
*/
|
||||
int icom_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo)
|
||||
int icom_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo)
|
||||
{
|
||||
unsigned char splitbuf[MAXFRAMELEN];
|
||||
int split_len, retval, satmode = 0;
|
||||
|
@ -6304,7 +6168,6 @@ int icom_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo)
|
|||
switch (splitbuf[1])
|
||||
{
|
||||
case S_SPLT_OFF:
|
||||
case S_DUP_OFF:
|
||||
*split = RIG_SPLIT_OFF;
|
||||
break;
|
||||
|
||||
|
@ -6313,6 +6176,7 @@ int icom_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo)
|
|||
break;
|
||||
|
||||
// The same command indicates repeater shift state, which means that split is off
|
||||
case S_DUP_OFF:
|
||||
case S_DUP_M:
|
||||
case S_DUP_P:
|
||||
case S_DUP_DD_RPS:
|
||||
|
@ -6331,13 +6195,15 @@ int icom_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo)
|
|||
rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode);
|
||||
}
|
||||
|
||||
// Update cache early for icom_get_split_vfos()
|
||||
rs->cache.split = *split;
|
||||
|
||||
icom_get_split_vfos(rig, &rs->rx_vfo, &rs->tx_vfo);
|
||||
|
||||
*tx_vfo = rs->tx_vfo;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n",
|
||||
__func__, rig_strvfo(vfo), rig_strvfo(rs->rx_vfo),
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: rx_vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n",
|
||||
__func__, rig_strvfo(rx_vfo), rig_strvfo(rs->rx_vfo),
|
||||
rig_strvfo(rs->tx_vfo), *split);
|
||||
|
||||
RETURNFUNC(RIG_OK);
|
||||
|
@ -6763,31 +6629,20 @@ int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
|
|||
|
||||
rig->state.cache.satmode = satmode;
|
||||
icom_satmode_fix(rig, satmode);
|
||||
}
|
||||
|
||||
// turning satmode on/off can change the tx/rx vfos
|
||||
// when in satmode split=off always
|
||||
if (VFO_HAS_MAIN_SUB_A_B_ONLY)
|
||||
{
|
||||
vfo_t tx_vfo;
|
||||
split_t split;
|
||||
|
||||
// update split status
|
||||
retval = icom_get_split_vfo(rig, RIG_VFO_CURR, &split, &tx_vfo);
|
||||
|
||||
if (retval != RIG_OK) { RETURNFUNC(retval); }
|
||||
|
||||
rs->tx_vfo = RIG_VFO_A;
|
||||
|
||||
if (rs->cache.split != RIG_SPLIT_OFF)
|
||||
// Turning satmode ON/OFF can change the TX/RX VFOs
|
||||
// Split is OFF always in satmode
|
||||
if (VFO_HAS_MAIN_SUB_A_B_ONLY)
|
||||
{
|
||||
// must have turned off satmode
|
||||
rs->tx_vfo = RIG_VFO_B;
|
||||
}
|
||||
else if (status)
|
||||
{
|
||||
// turned on satmode so tx is always Sub
|
||||
rs->tx_vfo = RIG_VFO_SUB;
|
||||
vfo_t tx_vfo;
|
||||
split_t split;
|
||||
|
||||
// Update split status (updates rig state/cache internally)
|
||||
retval = icom_get_split_vfo(rig, RIG_VFO_CURR, &split, &tx_vfo);
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
RETURNFUNC(retval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -345,8 +345,8 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq,
|
|||
rmode_t tx_mode, pbwidth_t tx_width);
|
||||
int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq,
|
||||
rmode_t *tx_mode, pbwidth_t *tx_width);
|
||||
int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo);
|
||||
int icom_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo);
|
||||
int icom_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo);
|
||||
int icom_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo);
|
||||
int icom_mem_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo);
|
||||
int icom_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts);
|
||||
int icom_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts);
|
||||
|
|
179
src/rig.c
179
src/rig.c
|
@ -1341,7 +1341,7 @@ int HAMLIB_API rig_open(RIG *rig)
|
|||
* Maybe the backend has something to initialize
|
||||
* In case of failure, just close down and report error code.
|
||||
*/
|
||||
int retry_save = rs->rigport.retry;
|
||||
short retry_save = rs->rigport.retry;
|
||||
rs->rigport.retry = 0;
|
||||
|
||||
if (caps->rig_open != NULL)
|
||||
|
@ -1395,12 +1395,12 @@ int HAMLIB_API rig_open(RIG *rig)
|
|||
{
|
||||
rs->tx_vfo = rs->current_vfo;
|
||||
}
|
||||
else // no get_vfo so set some sensible defaults
|
||||
else
|
||||
{
|
||||
//int backend_num = RIG_BACKEND_NUM(rig->caps->rig_model);
|
||||
// No get_vfo available, so set some sensible defaults
|
||||
rs->tx_vfo = RIG_VFO_TX;
|
||||
|
||||
// If we haven't gotten the vfo by now we will default to VFO_CURR
|
||||
// If we haven't gotten the VFO by now we will default to VFO_CURR
|
||||
if (rs->current_vfo == RIG_VFO_NONE) { rs->current_vfo = RIG_VFO_CURR; }
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: vfo_curr=%s, tx_vfo=%s\n", __func__,
|
||||
|
@ -1438,13 +1438,8 @@ int HAMLIB_API rig_open(RIG *rig)
|
|||
rig_set_parm(rig, RIG_PARM_SCREENSAVER, parm_value);
|
||||
}
|
||||
|
||||
// read frequency to update internal status
|
||||
// freq_t freq;
|
||||
// if (caps->get_freq) rig_get_freq(rig, RIG_VFO_A, &freq);
|
||||
// if (caps->get_freq) rig_get_freq(rig, RIG_VFO_B, &freq);
|
||||
|
||||
// prime the freq and mode settings
|
||||
// don't care about the return here -- if it doesn't work so be it
|
||||
// read frequency, mode and split to update internal status
|
||||
// don't care about the command return values here -- if they don't succeed, so be it
|
||||
freq_t freq;
|
||||
|
||||
if (rig->caps->get_freq)
|
||||
|
@ -1456,16 +1451,11 @@ int HAMLIB_API rig_open(RIG *rig)
|
|||
split_t split = RIG_SPLIT_OFF;
|
||||
vfo_t tx_vfo = RIG_VFO_NONE;
|
||||
rig_get_freq(rig, RIG_VFO_B, &freq);
|
||||
// TODO: Does this actually update rs->tx_vfo and split status?
|
||||
retval = rig_get_split_vfo(rig, RIG_VFO_RX, &split, &tx_vfo);
|
||||
if (retval == RIG_OK && caps->get_split_vfo != NULL)
|
||||
{
|
||||
rs->tx_vfo = tx_vfo;
|
||||
}
|
||||
rig_get_split_vfo(rig, RIG_VFO_RX, &split, &tx_vfo);
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Current split=%d, tx_vfo=%s\n", __func__,
|
||||
__LINE__, split, rig_strvfo(tx_vfo));
|
||||
rmode_t mode;
|
||||
pbwidth_t width = 2400; // we'll use 2400Hz as default width
|
||||
pbwidth_t width = 2400; // use 2400Hz as default width
|
||||
|
||||
if (rig->caps->get_mode)
|
||||
{
|
||||
|
@ -1912,24 +1902,24 @@ int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
|||
|
||||
if (rig->state.doppler == 0)
|
||||
{
|
||||
if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN || (vfo == RIG_VFO_CURR && rig->state.current_vfo == RIG_VFO_A))
|
||||
{
|
||||
if (rig->state.cache.freqMainA != freq && (((int)freq % 10) != 0))
|
||||
if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN || (vfo == RIG_VFO_CURR && rig->state.current_vfo == RIG_VFO_A))
|
||||
{
|
||||
rig->state.doppler = 1;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): potential doppler detected because old freq %f != new && new freq has 1Hz or such values\n", __func__, __LINE__, rig->state.cache.freqMainA);
|
||||
}
|
||||
freq += rig->state.offset_vfoa;
|
||||
}
|
||||
else if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB || (vfo == RIG_VFO_CURR && rig->state.current_vfo == RIG_VFO_B))
|
||||
{
|
||||
if (rig->state.cache.freqMainB != freq && ((int)freq % 10) != 0)
|
||||
if (rig->state.cache.freqMainA != freq && (((int)freq % 10) != 0))
|
||||
{
|
||||
rig->state.doppler = 1;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): potential doppler detected because old freq %f != new && new freq has 1Hz or such values\n", __func__, __LINE__, rig->state.cache.freqMainA);
|
||||
}
|
||||
freq += rig->state.offset_vfoa;
|
||||
}
|
||||
else if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB || (vfo == RIG_VFO_CURR && rig->state.current_vfo == RIG_VFO_B))
|
||||
{
|
||||
rig->state.doppler = 1;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): potential doppler detected because old freq %f != new && new freq has 1Hz or such values\n", __func__, __LINE__, rig->state.cache.freqMainB);
|
||||
}
|
||||
freq += rig->state.offset_vfob;
|
||||
}
|
||||
if (rig->state.cache.freqMainB != freq && ((int)freq % 10) != 0)
|
||||
{
|
||||
rig->state.doppler = 1;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): potential doppler detected because old freq %f != new && new freq has 1Hz or such values\n", __func__, __LINE__, rig->state.cache.freqMainB);
|
||||
}
|
||||
freq += rig->state.offset_vfob;
|
||||
}
|
||||
}
|
||||
|
||||
if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { freq += rig->state.offset_vfoa; }
|
||||
|
@ -2480,7 +2470,6 @@ int HAMLIB_API rig_get_freqs(RIG *rig, freq_t *freqA, freq_t freqB)
|
|||
// we will attempt to avoid vfo swapping in this routine
|
||||
|
||||
return (-RIG_ENIMPL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -2593,18 +2582,27 @@ int HAMLIB_API rig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
|||
int rc2;
|
||||
vfo_t curr_vfo;
|
||||
|
||||
// TODO: Add a universal check (based on cache) if mode actually needs to be changed, to prevent VFO swapping
|
||||
// if not a targetable rig we will only set mode on VFOB if it is changing
|
||||
if (rig->state.cache.modeMainB == mode)
|
||||
// If the rig does not support targetable mode, only set mode on an unselected if it is changing
|
||||
// to avoid unnecessary VFO swapping
|
||||
if (vfo != rig->state.current_vfo)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: VFOB mode not changing so ignoring\n",
|
||||
__func__);
|
||||
ELAPSED2;
|
||||
LOCK(0);
|
||||
RETURNFUNC(RIG_OK);
|
||||
freq_t cache_freq;
|
||||
rmode_t cache_mode;
|
||||
pbwidth_t cache_width;
|
||||
int cache_ms_freq, cache_ms_mode, cache_ms_width;
|
||||
|
||||
rig_get_cache(rig, vfo, &cache_freq, &cache_ms_freq, &cache_mode, &cache_ms_mode, &cache_width, &cache_ms_width);
|
||||
if (cache_mode == mode)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: mode not changing, so ignoring\n",
|
||||
__func__);
|
||||
ELAPSED2;
|
||||
LOCK(0);
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: not targetable need vfo swap\n", __func__);
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: mode is not targetable, VFO swapping needed\n", __func__);
|
||||
|
||||
if (!caps->set_vfo)
|
||||
{
|
||||
|
@ -5339,11 +5337,51 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
|
|||
return RIG_OK;
|
||||
}
|
||||
|
||||
if (rx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_NONE)
|
||||
{
|
||||
ELAPSED2;
|
||||
RETURNFUNC(-RIG_EINVAL);
|
||||
}
|
||||
|
||||
// We fix up vfos for non-satmode rigs only
|
||||
if (caps->has_get_func & RIG_FUNC_SATMODE)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: satmode rig...not fixing up vfos rx=%s tx=%s\n",
|
||||
__func__, rig_strvfo(rx_vfo), rig_strvfo(tx_vfo));
|
||||
if (tx_vfo == RIG_VFO_CURR)
|
||||
{
|
||||
tx_vfo = rs->current_vfo;
|
||||
rx_vfo = vfo_fixup(rig, RIG_VFO_OTHER, split);
|
||||
}
|
||||
|
||||
// Fix up only special cases to allow ambiguous parameters
|
||||
if (rx_vfo == tx_vfo)
|
||||
{
|
||||
switch (tx_vfo)
|
||||
{
|
||||
case RIG_VFO_MAIN:
|
||||
rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_SUB : RIG_VFO_MAIN;
|
||||
break;
|
||||
|
||||
case RIG_VFO_A:
|
||||
rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_B : RIG_VFO_A;
|
||||
break;
|
||||
|
||||
case RIG_VFO_SUB:
|
||||
rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_MAIN : RIG_VFO_SUB;
|
||||
break;
|
||||
|
||||
case RIG_VFO_B:
|
||||
rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_A : RIG_VFO_B;
|
||||
break;
|
||||
|
||||
default:
|
||||
tx_vfo = rs->current_vfo;
|
||||
rx_vfo = vfo_fixup(rig, RIG_VFO_OTHER, split);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: rig supports satmode, not fixing up vfos: rx=%s tx=%s\n",
|
||||
__func__, rig_strvfo(rx_vfo), rig_strvfo(tx_vfo));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5364,11 +5402,15 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
|
|||
case RIG_VFO_B:
|
||||
rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_A : RIG_VFO_B;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rx_vfo = vfo_fixup(rig, rx_vfo, split);
|
||||
tx_vfo = vfo_fixup(rig, tx_vfo, split);
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: final rxvfo=%s, txvfo=%s, split=%d\n",
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: final rx_vfo=%s, tx_vfo=%s, split=%d\n",
|
||||
__func__,
|
||||
rig_strvfo(rx_vfo), rig_strvfo(tx_vfo), split);
|
||||
}
|
||||
|
@ -5378,7 +5420,9 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
|
|||
|
||||
if ((!(caps->targetable_vfo & RIG_TARGETABLE_FREQ))
|
||||
&& (!(caps->rig_model == RIG_MODEL_NETRIGCTL)))
|
||||
{
|
||||
rig_set_vfo(rig, rx_vfo);
|
||||
}
|
||||
|
||||
// Check if RX VFO is the currently active VFO and we don't need to change the VFO
|
||||
if (rx_vfo == RIG_VFO_CURR || rx_vfo == rs->current_vfo)
|
||||
|
@ -5386,7 +5430,7 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
|
|||
// for non-targetable VFOs we will not set split again
|
||||
if (rs->cache.split == split && rs->cache.split_vfo == tx_vfo)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): split already set...ignoring\n", __func__,
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): split already on, ignoring\n", __func__,
|
||||
__LINE__);
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
|
@ -5397,10 +5441,18 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
|
|||
if (retcode == RIG_OK)
|
||||
{
|
||||
// Only update cache on success
|
||||
rs->rx_vfo = rx_vfo;
|
||||
rs->tx_vfo = tx_vfo;
|
||||
rs->rx_vfo = rs->current_vfo;
|
||||
rs->cache.split = split;
|
||||
rs->cache.split_vfo = tx_vfo;
|
||||
if (split == RIG_SPLIT_OFF)
|
||||
{
|
||||
rs->tx_vfo = rs->current_vfo;
|
||||
rs->cache.split_vfo = rs->current_vfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs->tx_vfo = tx_vfo;
|
||||
rs->cache.split_vfo = tx_vfo;
|
||||
}
|
||||
}
|
||||
|
||||
elapsed_ms(&rs->cache.time_split, HAMLIB_ELAPSED_SET);
|
||||
|
@ -5448,10 +5500,28 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
|
|||
if (retcode == RIG_OK)
|
||||
{
|
||||
// Only update cache on success
|
||||
rs->rx_vfo = rx_vfo;
|
||||
rs->tx_vfo = tx_vfo;
|
||||
rs->cache.split = split;
|
||||
rs->cache.split_vfo = tx_vfo;
|
||||
if (split == RIG_SPLIT_OFF)
|
||||
{
|
||||
if (caps->targetable_vfo & RIG_TARGETABLE_FREQ)
|
||||
{
|
||||
rs->rx_vfo = rx_vfo;
|
||||
rs->tx_vfo = rx_vfo;
|
||||
rs->cache.split_vfo = rx_vfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs->rx_vfo = rs->current_vfo;
|
||||
rs->tx_vfo = rs->current_vfo;
|
||||
rs->cache.split_vfo = rs->current_vfo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rs->rx_vfo = rx_vfo;
|
||||
rs->tx_vfo = tx_vfo;
|
||||
rs->cache.split_vfo = tx_vfo;
|
||||
}
|
||||
}
|
||||
|
||||
elapsed_ms(&rs->cache.time_split, HAMLIB_ELAPSED_SET);
|
||||
|
@ -5540,6 +5610,7 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
|
|||
if (retcode == RIG_OK)
|
||||
{
|
||||
// Only update cache on success
|
||||
rs->tx_vfo = *tx_vfo;
|
||||
rs->cache.split = *split;
|
||||
rs->cache.split_vfo = *tx_vfo;
|
||||
elapsed_ms(&rs->cache.time_split, HAMLIB_ELAPSED_SET);
|
||||
|
|
Ładowanie…
Reference in New Issue