Streamline VFO targeting and split functionality. Rewrite Icom backend routines to always avoid VFO swapping is the rig supports the 'targetable' commands 0x25 and 0x26. Work in progress.

pull/1481/head
Mikael Nousiainen 2023-10-29 10:28:36 +02:00
rodzic 325277f269
commit 8ab8aafe48
17 zmienionych plików z 779 dodań i 865 usunięć

Wyświetl plik

@ -540,9 +540,17 @@ static int dummy_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
case RIG_VFO_MAIN: case RIG_VFO_MAIN:
case RIG_VFO_A: width = priv->vfo_a.width; break; case RIG_VFO_A: width = priv->vfo_a.width; break;
case RIG_VFO_MAIN_A: width = priv->vfo_maina.width; break;
case RIG_VFO_MAIN_B: width = priv->vfo_mainb.width; break;
case RIG_VFO_SUB: case RIG_VFO_SUB:
case RIG_VFO_B: width = priv->vfo_b.width; break; case RIG_VFO_B: width = priv->vfo_b.width; break;
case RIG_VFO_SUB_A: width = priv->vfo_suba.width; break;
case RIG_VFO_SUB_B: width = priv->vfo_subb.width; break;
case RIG_VFO_C: width = priv->vfo_c.width; break; case RIG_VFO_C: width = priv->vfo_c.width; break;
} }
} }
@ -552,9 +560,17 @@ static int dummy_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
case RIG_VFO_MAIN: case RIG_VFO_MAIN:
case RIG_VFO_A: priv->vfo_a.mode = mode; priv->vfo_a.width = width; break; case RIG_VFO_A: priv->vfo_a.mode = mode; priv->vfo_a.width = width; break;
case RIG_VFO_MAIN_A: priv->vfo_maina.mode = mode; priv->vfo_maina.width = width; break;
case RIG_VFO_MAIN_B: priv->vfo_mainb.mode = mode; priv->vfo_mainb.width = width; break;
case RIG_VFO_SUB: case RIG_VFO_SUB:
case RIG_VFO_B: priv->vfo_b.mode = mode; priv->vfo_b.width = width; break; case RIG_VFO_B: priv->vfo_b.mode = mode; priv->vfo_b.width = width; break;
case RIG_VFO_SUB_A: priv->vfo_suba.mode = mode; priv->vfo_suba.width = width; break;
case RIG_VFO_SUB_B: priv->vfo_subb.mode = mode; priv->vfo_subb.width = width; break;
case RIG_VFO_C: priv->vfo_c.mode = mode; priv->vfo_c.width = width; break; case RIG_VFO_C: priv->vfo_c.mode = mode; priv->vfo_c.width = width; break;
default: default:
@ -941,11 +957,11 @@ static int dummy_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
int retval; int retval;
ENTERFUNC; ENTERFUNC;
rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), tx_freq);
retval = dummy_set_freq(rig, vfo, tx_freq); retval = dummy_set_freq(rig, vfo, tx_freq);
priv->curr->tx_freq = tx_freq; priv->curr->tx_freq = tx_freq;
rig_debug(RIG_DEBUG_VERBOSE, "%s: priv->curr->tx_freq = %.0f\n", __func__, rig_debug(RIG_DEBUG_VERBOSE, "%s: freq=%.0f\n", __func__, tx_freq);
priv->curr->tx_freq);
RETURNFUNC(retval); RETURNFUNC(retval);
} }
@ -953,15 +969,15 @@ static int dummy_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
static int dummy_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) static int dummy_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
{ {
struct dummy_priv_data *priv = (struct dummy_priv_data *)rig->state.priv; int retval;
ENTERFUNC; ENTERFUNC;
rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo));
*tx_freq = priv->curr->tx_freq; retval = dummy_get_freq(rig, vfo, tx_freq);
rig_debug(RIG_DEBUG_VERBOSE, "%s: priv->curr->tx_freq = %.0f\n", __func__, rig_debug(RIG_DEBUG_VERBOSE, "%s: freq=%.0f\n", __func__, *tx_freq);
priv->curr->tx_freq);
RETURNFUNC(RIG_OK); RETURNFUNC(retval);
} }
static int dummy_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, static int dummy_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode,
@ -969,41 +985,50 @@ static int dummy_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode,
{ {
struct dummy_priv_data *priv = (struct dummy_priv_data *)rig->state.priv; struct dummy_priv_data *priv = (struct dummy_priv_data *)rig->state.priv;
channel_t *curr = priv->curr; channel_t *curr = priv->curr;
int retval;
ENTERFUNC; ENTERFUNC;
rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s tx_mode=%s tx_width=%ld\n",
__func__, rig_strvfo(vfo), rig_strrmode(tx_mode), tx_width);
retval = dummy_set_mode(rig, vfo, tx_mode, tx_width);
curr->tx_mode = tx_mode; curr->tx_mode = tx_mode;
if (RIG_PASSBAND_NOCHANGE == tx_width) { RETURNFUNC(RIG_OK); } if (RIG_PASSBAND_NOCHANGE == tx_width)
{
RETURNFUNC(retval);
}
curr->tx_width = tx_width; curr->tx_width = tx_width;
RETURNFUNC(RIG_OK); RETURNFUNC(retval);
} }
static int dummy_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, static int dummy_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode,
pbwidth_t *tx_width) pbwidth_t *tx_width)
{ {
struct dummy_priv_data *priv = (struct dummy_priv_data *)rig->state.priv; int retval;
const channel_t *curr = priv->curr;
ENTERFUNC; ENTERFUNC;
rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo));
*tx_mode = curr->tx_mode; retval = dummy_get_mode(rig, vfo, tx_mode, tx_width);
*tx_width = curr->tx_width;
RETURNFUNC(RIG_OK); rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s tx_mode=%s tx_width=%ld\n",
__func__, rig_strvfo(vfo), rig_strrmode(*tx_mode), *tx_width);
RETURNFUNC(retval);
} }
static int dummy_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) static int dummy_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
{ {
struct dummy_priv_data *priv = (struct dummy_priv_data *)rig->state.priv; struct dummy_priv_data *priv = (struct dummy_priv_data *)rig->state.priv;
channel_t *curr = priv->curr;
ENTERFUNC; ENTERFUNC;
rig_debug(RIG_DEBUG_VERBOSE, "%s: split=%d, vfo=%s, tx_vfo=%s\n", rig_debug(RIG_DEBUG_VERBOSE, "%s: split=%d, vfo=%s, tx_vfo=%s\n",
__func__, split, rig_strvfo(vfo), rig_strvfo(tx_vfo)); __func__, split, rig_strvfo(vfo), rig_strvfo(tx_vfo));
curr->split = split;
priv->split = split;
priv->tx_vfo = tx_vfo; priv->tx_vfo = tx_vfo;
RETURNFUNC(RIG_OK); RETURNFUNC(RIG_OK);
@ -1014,10 +1039,14 @@ static int dummy_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split,
vfo_t *tx_vfo) vfo_t *tx_vfo)
{ {
struct dummy_priv_data *priv = (struct dummy_priv_data *)rig->state.priv; struct dummy_priv_data *priv = (struct dummy_priv_data *)rig->state.priv;
const channel_t *curr = priv->curr;
ENTERFUNC; ENTERFUNC;
*split = curr->split;
*split = priv->split;
*tx_vfo = priv->tx_vfo;
rig_debug(RIG_DEBUG_VERBOSE, "%s: split=%d, vfo=%s, tx_vfo=%s\n",
__func__, *split, rig_strvfo(vfo), rig_strvfo(*tx_vfo));
RETURNFUNC(RIG_OK); RETURNFUNC(RIG_OK);
} }
@ -2311,6 +2340,13 @@ struct rig_caps dummy_caps =
[LVL_SPECTRUM_REF] = {.min = {.f = -30.0f}, .max = {.f = 10.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_REF] = {.min = {.f = -30.0f}, .max = {.f = 10.0f}, .step = {.f = 0.5f}},
[LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}},
}, },
.parm_gran = {
[PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}},
[PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM"}},
[PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}},
[PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}},
[PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}},
},
.ctcss_list = common_ctcss_list, .ctcss_list = common_ctcss_list,
.dcs_list = full_dcs_list, .dcs_list = full_dcs_list,
.chan_list = { .chan_list = {

Wyświetl plik

@ -735,7 +735,7 @@ const struct rig_caps ic7300_caps =
[PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}},
[PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}},
[PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}},
[PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT, BUG, PADDLE"}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}},
}, },
.ext_tokens = ic7300_ext_tokens, .ext_tokens = ic7300_ext_tokens,
@ -978,7 +978,7 @@ struct rig_caps ic9700_caps =
[PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM"}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM"}},
[PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}},
[PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}},
[PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT, BUG, PADDLE"}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}},
}, },
.ext_tokens = ic9700_ext_tokens, .ext_tokens = ic9700_ext_tokens,
.extlevels = icom_ext_levels, .extlevels = icom_ext_levels,
@ -1572,7 +1572,7 @@ const struct rig_caps ic905_caps =
[PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM,BAND23CM,BAND13CM,BAND3CM"}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM,BAND23CM,BAND13CM,BAND3CM"}},
[PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}},
[PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}},
[PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT, BUG, PADDLE"}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}},
}, },
.ext_tokens = ic705_ext_tokens, .ext_tokens = ic705_ext_tokens,
.extlevels = icom_ext_levels, .extlevels = icom_ext_levels,

Wyświetl plik

@ -157,7 +157,7 @@ const struct rig_caps ic7410_caps =
.parm_gran = { .parm_gran = {
[PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}},
[PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}},
[PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT, BUG, PADDLE"}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}},
}, },
.ctcss_list = common_ctcss_list, .ctcss_list = common_ctcss_list,

Wyświetl plik

@ -315,7 +315,7 @@ struct rig_caps ic7600_caps =
[PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}},
[PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}},
[PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} },
[PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT, BUG, PADDLE"}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}},
}, },
.ext_tokens = ic7600_ext_tokens, .ext_tokens = ic7600_ext_tokens,

Wyświetl plik

@ -398,7 +398,7 @@ struct rig_caps ic7610_caps =
[PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}},
[PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}},
[PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}},
[PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT, BUG, PADDLE"}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}},
}, },
.ext_tokens = ic7610_ext_tokens, .ext_tokens = ic7610_ext_tokens,

Wyświetl plik

@ -282,7 +282,7 @@ const struct rig_caps ic785x_caps =
[PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}},
[PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}},
[PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}},
[PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT, BUG, PADDLE"}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}},
}, },
.ext_tokens = ic785x_ext_tokens, .ext_tokens = ic785x_ext_tokens,

Wyświetl plik

@ -69,14 +69,14 @@ int ic821h_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
split; // we emulate satmode of other rigs since we apparently can't query split; // we emulate satmode of other rigs since we apparently can't query
rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo==MAIN so assuming sat mode=%d\n", rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo==MAIN so assuming sat mode=%d\n",
__func__, rig->state.cache.satmode); __func__, rig->state.cache.satmode);
priv->tx_vfo = split == RIG_SPLIT_ON ? RIG_VFO_SUB : RIG_VFO_MAIN; rig->state.tx_vfo = split == RIG_SPLIT_ON ? RIG_VFO_SUB : RIG_VFO_MAIN;
// the IC821 seems to be backwards in satmode -- setting Main select Sub and vice versa // the IC821 seems to be backwards in satmode -- setting Main select Sub and vice versa
retval = rig_set_vfo(rig, RIG_VFO_SUB); retval = rig_set_vfo(rig, RIG_VFO_SUB);
} }
else if (tx_vfo == RIG_VFO_A) else if (tx_vfo == RIG_VFO_A)
{ {
retval = rig_set_vfo(rig, RIG_VFO_A); retval = rig_set_vfo(rig, RIG_VFO_A);
priv->tx_vfo = split == RIG_SPLIT_ON ? RIG_VFO_B : RIG_VFO_A; rig->state.tx_vfo = split == RIG_SPLIT_ON ? RIG_VFO_B : RIG_VFO_A;
} }
else else
{ {

Wyświetl plik

@ -142,7 +142,7 @@ const struct rig_caps ic9100_caps =
[PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}},
[PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}},
[PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}},
[PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT, BUG, PADDLE"}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}},
}, },
.ctcss_list = common_ctcss_list, .ctcss_list = common_ctcss_list,

Plik diff jest za duży Load Diff

Wyświetl plik

@ -253,22 +253,28 @@ struct icom_priv_data
int civ_731_mode; /*!< Off: freqs on 10 digits, On: freqs on 8 digits */ int civ_731_mode; /*!< Off: freqs on 10 digits, On: freqs on 8 digits */
int no_xchg; /*!< Off: use VFO XCHG to set other VFO, On: use set VFO to set other VFO */ int no_xchg; /*!< Off: use VFO XCHG to set other VFO, On: use set VFO to set other VFO */
int no_1a_03_cmd; /*!< Rig doesn't tell IF widths */ int no_1a_03_cmd; /*!< Rig doesn't tell IF widths */
int split_on; /*!< Record split state */ int split_on_deprecated; /*!< @deprecated Use rig_cache.split - Record split state */
pltstate_t *pltstate; /*!< Only on optoscan */ pltstate_t *pltstate; /*!< Only on optoscan */
int serial_USB_echo_off; /*!< USB is not set to echo */ int serial_USB_echo_off; /*!< USB is not set to echo */
/* we track vfos internally for use with different functions like split */
/* this allows queries using CURR_VFO and Main/Sub to behave */ /**
vfo_t rx_vfo; * Icom backends track VFOs internally for use with different functions like split.
vfo_t tx_vfo; * This allows queries using CURR_VFO and Main/Sub to work correctly.
freq_t curr_freq; /*!< Our current freq depending on which vfo is selected */ *
freq_t main_freq; /*!< Track last setting of main -- not being used yet */ * The fields in this struct are no longer used, because rig_state and rig_cache structs provide
freq_t sub_freq; /*!< Track last setting of sub -- not being used yet */ * the same functionality for all rigs globally.
freq_t maina_freq; */
freq_t mainb_freq; vfo_t rx_vfo_deprecated; /*!< @deprecated Use rig_state.rx_vfo */
freq_t suba_freq; vfo_t tx_vfo_deprecated; /*!< @deprecated Use rig_state.tx_vfo */
freq_t subb_freq; freq_t curr_freq_deprecated; /*!< @deprecated Use rig_cache.freqCurr - Our current freq depending on which vfo is selected */
freq_t vfoa_freq; /*!< Track last setting of vfoa -- used to return last freq when ptt is asserted */ freq_t main_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainA - Track last setting of main -- not being used yet */
freq_t vfob_freq; /*!< Track last setting of vfob -- used to return last freq when ptt is asserted */ freq_t sub_freq_deprecated; /*!< @deprecated Use rig_cache.freqSubA - Track last setting of sub -- not being used yet */
freq_t maina_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainA */
freq_t mainb_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainB */
freq_t suba_freq_deprecated; /*!< @deprecated Use rig_cache.freqSubA */
freq_t subb_freq_deprecated; /*!< @deprecated Use rig_cache.freqSubB */
freq_t vfoa_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainA - Track last setting of vfoa -- used to return last freq when ptt is asserted */
freq_t vfob_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainB - 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 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 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 x1cx03cmdfails; /*!< This will get set if the 0x1c 0x03 command fails so we try just once */
@ -277,7 +283,7 @@ struct icom_priv_data
unsigned char datamode; /*!< Current datamode */ unsigned char datamode; /*!< Current datamode */
int spectrum_scope_count; /*!< Number of spectrum scopes, calculated from caps */ int spectrum_scope_count; /*!< Number of spectrum scopes, calculated from caps */
struct icom_spectrum_scope_cache spectrum_scope_cache[HAMLIB_MAX_SPECTRUM_SCOPES]; /*!< Cached Icom spectrum scope data used during reception of the data. The array index must match the scope ID. */ struct icom_spectrum_scope_cache spectrum_scope_cache[HAMLIB_MAX_SPECTRUM_SCOPES]; /*!< Cached Icom spectrum scope data used during reception of the data. The array index must match the scope ID. */
freq_t other_freq; /*!< Our other freq depending on which vfo is selected */ freq_t other_freq_deprecated; /*!< @deprecated Use rig_cache.freqOther - Our other freq depending on which vfo is selected */
int vfo_flag; // used to skip vfo check when frequencies are equal int vfo_flag; // used to skip vfo check when frequencies are equal
}; };

Wyświetl plik

@ -98,6 +98,7 @@
#define C_CTL_RIT 0x21 /* RIT/XIT control */ #define C_CTL_RIT 0x21 /* RIT/XIT control */
#define C_CTL_DSD 0x22 /* D-STAR Data */ #define C_CTL_DSD 0x22 /* D-STAR Data */
#define C_SEND_SEL_FREQ 0x25 /* Send/Recv sel/unsel VFO frequency */ #define C_SEND_SEL_FREQ 0x25 /* Send/Recv sel/unsel VFO frequency */
#define C_SEND_SEL_MODE 0x26 /* Send/Recv sel/unsel VFO mode & filter */
#define C_CTL_SCP 0x27 /* Scope control & data */ #define C_CTL_SCP 0x27 /* Scope control & data */
#define C_SND_VOICE 0x28 /* Transmit Voice Memory Contents */ #define C_SND_VOICE 0x28 /* Transmit Voice Memory Contents */
#define C_CTL_MTEXT 0x70 /* Microtelecom Extension */ #define C_CTL_MTEXT 0x70 /* Microtelecom Extension */
@ -160,7 +161,7 @@
#define S_DUAL 0xc2 /* Dual watch (0 = off, 1 = on) */ #define S_DUAL 0xc2 /* Dual watch (0 = off, 1 = on) */
#define S_MAIN 0xd0 /* Select MAIN band */ #define S_MAIN 0xd0 /* Select MAIN band */
#define S_SUB 0xd1 /* Select SUB band */ #define S_SUB 0xd1 /* Select SUB band */
#define S_SUB_SEL 0xd2 /* Read/Set Main/Sub selection */ #define S_BAND_SEL 0xd2 /* Read/Set Main/Sub band selection */
#define S_FRONTWIN 0xe0 /* Select front window */ #define S_FRONTWIN 0xe0 /* Select front window */
/* /*
@ -359,8 +360,9 @@
/* /*
* Transmit control (C_CTL_PTT) subcommands * Transmit control (C_CTL_PTT) subcommands
*/ */
#define S_PTT 0x00 #define S_PTT 0x00
#define S_ANT_TUN 0x01 /* Auto tuner 0=OFF, 1 = ON, 2=Start Tuning */ #define S_ANT_TUN 0x01 /* Auto tuner 0=OFF, 1 = ON, 2=Start Tuning */
#define S_RD_TX_FREQ 0x03 /* Read transmit frequency */
/* /*
* Band Edge control (C_CTL_EDGE) subcommands * Band Edge control (C_CTL_EDGE) subcommands

Wyświetl plik

@ -891,7 +891,6 @@ int x108g_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt)
*/ */
static int x108g_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) static int x108g_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
{ {
struct icom_priv_data *priv = (struct icom_priv_data *)rig->state.priv;
unsigned char ackbuf[MAXFRAMELEN]; unsigned char ackbuf[MAXFRAMELEN];
int ack_len = sizeof(ackbuf), rc; int ack_len = sizeof(ackbuf), rc;
int split_sc; int split_sc;
@ -907,7 +906,7 @@ static int x108g_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
case RIG_SPLIT_ON: case RIG_SPLIT_ON:
split_sc = S_SPLT_ON; split_sc = S_SPLT_ON;
if (!priv->split_on) if (rig->state.cache.split == RIG_SPLIT_OFF)
{ {
/* ensure VFO A is Rx and VFO B is Tx as we assume that elsewhere */ /* ensure VFO A is Rx and VFO B is Tx as we assume that elsewhere */
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)) if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B))
@ -934,7 +933,7 @@ static int x108g_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
return -RIG_ERJCTED; return -RIG_ERJCTED;
} }
priv->split_on = RIG_SPLIT_ON == split; rig->state.cache.split = split;
return RIG_OK; return RIG_OK;
} }
@ -973,13 +972,17 @@ static int x108g_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
current VFO is VFO A and the split Tx VFO is always VFO B. These 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 assumptions allow us to deal with the lack of VFO and split
queries */ queries */
/* broken if user changes split on rig :( */
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
&& priv->split_on) /* broken if user changes split on rig :( */ && rig->state.cache.split != RIG_SPLIT_OFF)
{ {
/* VFO A/B style rigs swap VFO on split Tx so we need to disable /* VFO A/B style rigs swap VFO on split Tx so we need to disable
split for certainty */ split for certainty */
if (RIG_OK != (rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len);
ackbuf, &ack_len))) { return rc; } if (rc != RIG_OK)
{
return rc;
}
if (ack_len != 2 || ackbuf[0] != 0x0f) if (ack_len != 2 || ackbuf[0] != 0x0f)
{ {
@ -998,11 +1001,14 @@ static int x108g_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
if (RIG_OK != (rc = icom_set_vfo(rig, rx_vfo))) { return rc; } if (RIG_OK != (rc = icom_set_vfo(rig, rx_vfo))) { return rc; }
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
&& priv->split_on) && rig->state.cache.split != RIG_SPLIT_OFF)
{ {
/* Re-enable split */ /* Re-enable split */
if (RIG_OK != (rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len);
ackbuf, &ack_len))) { return rc; } if (rc != RIG_OK)
{
return rc;
}
} }
return rc; return rc;
@ -1043,13 +1049,17 @@ static int x108g_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode,
current VFO is VFO A and the split Tx VFO is always VFO B. These 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 assumptions allow us to deal with the lack of VFO and split
queries */ queries */
/* broken if user changes split on rig :( */
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
&& priv->split_on) /* broken if user changes split on rig :( */ && rig->state.cache.split != RIG_SPLIT_OFF)
{ {
/* VFO A/B style rigs swap VFO on split Tx so we need to disable /* VFO A/B style rigs swap VFO on split Tx so we need to disable
split for certainty */ split for certainty */
if (RIG_OK != (rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len);
ackbuf, &ack_len))) { return rc; } if (rc != RIG_OK)
{
return rc;
}
if (ack_len != 2 || ackbuf[0] != 0x0f) if (ack_len != 2 || ackbuf[0] != 0x0f)
{ {
@ -1069,13 +1079,15 @@ static int x108g_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode,
if (RIG_OK != (rc = icom_set_vfo(rig, rx_vfo))) { return rc; } if (RIG_OK != (rc = icom_set_vfo(rig, rx_vfo))) { return rc; }
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
&& priv->split_on) && rig->state.cache.split != RIG_SPLIT_OFF)
{ {
/* Re-enable split */ /* Re-enable split */
if (RIG_OK != (rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len);
ackbuf, &ack_len))) { return rc; } if (rc != RIG_OK)
{
return rc;
}
} }
return rc; return rc;
} }

Wyświetl plik

@ -60,6 +60,16 @@ int rig_set_cache_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
if (vfo == RIG_VFO_OTHER) { vfo = vfo_fixup(rig, vfo, rig->state.cache.split); } if (vfo == RIG_VFO_OTHER) { vfo = vfo_fixup(rig, vfo, rig->state.cache.split); }
if (vfo == rig->state.current_vfo)
{
rig->state.cache.modeCurr = mode;
if (width > 0)
{
rig->state.cache.widthCurr = width;
}
elapsed_ms(&rig->state.cache.time_modeCurr, HAMLIB_ELAPSED_SET);
}
switch (vfo) switch (vfo)
{ {
case RIG_VFO_ALL: // we'll use NONE to reset all VFO caches case RIG_VFO_ALL: // we'll use NONE to reset all VFO caches
@ -153,6 +163,12 @@ int rig_set_cache_freq(RIG *rig, vfo_t vfo, freq_t freq)
rig_strvfo(vfo), freq); rig_strvfo(vfo), freq);
} }
if (vfo == rig->state.current_vfo)
{
rig->state.cache.freqCurr = freq;
elapsed_ms(&rig->state.cache.time_freqCurr, flag);
}
switch (vfo) switch (vfo)
{ {
case RIG_VFO_ALL: // we'll use NONE to reset all VFO caches case RIG_VFO_ALL: // we'll use NONE to reset all VFO caches

Wyświetl plik

@ -515,7 +515,6 @@ static int multicast_publisher_write_data(multicast_publisher_args
return (RIG_OK); return (RIG_OK);
} }
#if 0 // disable until we figure out what to do about Windows poor performance
static int multicast_publisher_read_data(multicast_publisher_args static int multicast_publisher_read_data(multicast_publisher_args
const *mcast_publisher_args, size_t length, unsigned char *data) const *mcast_publisher_args, size_t length, unsigned char *data)
{ {
@ -558,7 +557,6 @@ static int multicast_publisher_read_data(multicast_publisher_args
return (RIG_OK); return (RIG_OK);
} }
#endif
#else #else
@ -638,7 +636,6 @@ static int multicast_publisher_write_data(const multicast_publisher_args
return (RIG_OK); return (RIG_OK);
} }
#if 0
static int multicast_publisher_read_data(const multicast_publisher_args static int multicast_publisher_read_data(const multicast_publisher_args
*mcast_publisher_args, size_t length, unsigned char *data) *mcast_publisher_args, size_t length, unsigned char *data)
{ {
@ -703,7 +700,6 @@ static int multicast_publisher_read_data(const multicast_publisher_args
return (RIG_OK); return (RIG_OK);
} }
#endif
#endif #endif
@ -827,7 +823,6 @@ int network_publish_rig_spectrum_data(RIG *rig, struct rig_spectrum_line *line)
RETURNFUNC2(RIG_OK); RETURNFUNC2(RIG_OK);
} }
#if 0
static int multicast_publisher_read_packet(multicast_publisher_args static int multicast_publisher_read_packet(multicast_publisher_args
const *mcast_publisher_args, const *mcast_publisher_args,
uint8_t *type, struct rig_spectrum_line *spectrum_line, uint8_t *type, struct rig_spectrum_line *spectrum_line,
@ -893,11 +888,10 @@ static int multicast_publisher_read_packet(multicast_publisher_args
return (RIG_OK); return (RIG_OK);
} }
#endif
void *multicast_publisher(void *arg) void *multicast_publisher(void *arg)
{ {
//unsigned char spectrum_data[HAMLIB_MAX_SPECTRUM_DATA]; unsigned char spectrum_data[HAMLIB_MAX_SPECTRUM_DATA];
char snapshot_buffer[HAMLIB_MAX_SNAPSHOT_PACKET_SIZE]; char snapshot_buffer[HAMLIB_MAX_SNAPSHOT_PACKET_SIZE];
struct multicast_publisher_args_s *args = (struct multicast_publisher_args_s *) struct multicast_publisher_args_s *args = (struct multicast_publisher_args_s *)
@ -923,29 +917,21 @@ void *multicast_publisher(void *arg)
while (rs->multicast_publisher_run == 1) while (rs->multicast_publisher_run == 1)
{ {
int i;
int result; int result;
static freq_t freqA, freqB, freqC;
static mode_t modeA, modeB, modeC;
static pbwidth_t widthA, widthB, widthC;
static ptt_t ptt;
static split_t split;
#if 0
result = multicast_publisher_read_packet(args, &packet_type, &spectrum_line, result = multicast_publisher_read_packet(args, &packet_type, &spectrum_line,
spectrum_data); spectrum_data);
#endif
if (result != RIG_OK) if (result != RIG_OK)
{ {
if (result == -RIG_ETIMEOUT) if (result == -RIG_ETIMEOUT)
{ {
// continue; continue;
} }
// TODO: how to detect closing of pipe, indicate with error code // TODO: how to detect closing of pipe, indicate with error code
// TODO: error handling, flush pipe in case of error? // TODO: error handling, flush pipe in case of error?
//hl_usleep(500 * 1000); hl_usleep(500 * 1000);
// continue; continue;
} }
result = snapshot_serialize(sizeof(snapshot_buffer), snapshot_buffer, rig, result = snapshot_serialize(sizeof(snapshot_buffer), snapshot_buffer, rig,
@ -959,10 +945,8 @@ void *multicast_publisher(void *arg)
continue; continue;
} }
#if 0
rig_debug(RIG_DEBUG_CACHE, "%s: sending rig snapshot data: %s\n", __func__, rig_debug(RIG_DEBUG_CACHE, "%s: sending rig snapshot data: %s\n", __func__,
snapshot_buffer); snapshot_buffer);
#endif
send_result = sendto( send_result = sendto(
socket_fd, socket_fd,
@ -978,68 +962,7 @@ void *multicast_publisher(void *arg)
rig_debug(RIG_DEBUG_ERR, "%s: error sending UDP packet: %s\n", __func__, rig_debug(RIG_DEBUG_ERR, "%s: error sending UDP packet: %s\n", __func__,
strerror(errno)); strerror(errno));
} }
for(i=0;i<5;++i)
{
hl_usleep(200*1000);
if (rig->state.cache.freqMainA != freqA)
{
freqA = rig->state.cache.freqMainA;
break;
}
if (rig->state.cache.freqMainB != freqB)
{
freqB = rig->state.cache.freqMainB;
break;
}
if (rig->state.cache.freqMainC != freqC)
{
freqC = rig->state.cache.freqMainC;
break;
}
if (rig->state.cache.ptt != ptt)
{
ptt = rig->state.cache.ptt;
break;
}
if (rig->state.cache.split != split)
{
split = rig->state.cache.split;
break;
}
if (rig->state.cache.modeMainA != modeA)
{
modeA = rig->state.cache.modeMainA;
break;
}
if (rig->state.cache.modeMainB != modeB)
{
modeB = rig->state.cache.modeMainB;
break;
}
if (rig->state.cache.modeMainC != modeC)
{
modeC = rig->state.cache.modeMainC;
break;
}
if (rig->state.cache.widthMainA != widthA)
{
widthA = rig->state.cache.widthMainA;
break;
}
if (rig->state.cache.widthMainB != widthB)
{
widthB = rig->state.cache.widthMainB;
break;
}
if (rig->state.cache.widthMainC != widthC)
{
widthC = rig->state.cache.widthMainC;
break;
}
}
} }
rs->multicast_publisher_run = 2; // stop value
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopping multicast publisher\n", __FILE__, rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopping multicast publisher\n", __FILE__,
__LINE__); __LINE__);

497
src/rig.c
Wyświetl plik

@ -21,6 +21,17 @@
* *
*/ */
/**
* TEST: Remove use of private state cache for VFOs/frequencies/modes in Icom backends and migrate to using the rig_state cache
* TEST: Ignore VFO targeting in all set/get split freq/mode commands and use the TX VFO set by \set_split_vfo command instead
* TEST: If split is not enabled, make \get_split_freq return 0 Hz frequency and get_split_mode return NONE mode with 0 Hz filter to indicate split is OFF
* TEST: set_split_freq and set_split_mode turn split ON if it is not enabled yet
* TODO: Make sure Icom set_freq/get_freq/set_mode/get_mode + set_split_freq/get_split_freq/set_split_mode/get_split_mode all use the 0x25 and 0x26 commands in a consistent way to avoid VFO swapping (on both the selected/unselected type rigs and Main/Sub VFO rigs)
*
* TODO: Test targeted set_freq/get_freq/set_mode/get_mode + split commands
* TODO: Test latest WSJT-X in split mode
*/
/** /**
* \addtogroup rig * \addtogroup rig
* @{ * @{
@ -669,6 +680,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model)
rs->vfo_comp = 0.0; /* override it with preferences */ rs->vfo_comp = 0.0; /* override it with preferences */
rs->current_vfo = RIG_VFO_CURR; /* we don't know yet! */ rs->current_vfo = RIG_VFO_CURR; /* we don't know yet! */
rs->rx_vfo = RIG_VFO_CURR; /* we don't know yet! */
rs->tx_vfo = RIG_VFO_CURR; /* we don't know yet! */ rs->tx_vfo = RIG_VFO_CURR; /* we don't know yet! */
rs->poll_interval = 0; // disable polling by default rs->poll_interval = 0; // disable polling by default
rs->lo_freq = 0; rs->lo_freq = 0;
@ -1396,18 +1408,6 @@ int HAMLIB_API rig_open(RIG *rig)
rig_debug(RIG_DEBUG_TRACE, "%s: vfo_curr=%s, tx_vfo=%s\n", __func__, rig_debug(RIG_DEBUG_TRACE, "%s: vfo_curr=%s, tx_vfo=%s\n", __func__,
rig_strvfo(rs->current_vfo), rig_strvfo(rs->tx_vfo)); rig_strvfo(rs->current_vfo), rig_strvfo(rs->tx_vfo));
#if 0 // done in the back end
if (backend_num == RIG_ICOM)
{
HAMLIB_TRACE;
rig_set_vfo(rig, RIG_VFO_A); // force VFOA as our startup VFO
rig_debug(RIG_DEBUG_TRACE, "%s: Icom rig so default vfo = %s\n", __func__,
rig_strvfo(rs->current_vfo));
}
#endif
if (rig->caps->set_vfo == NULL) if (rig->caps->set_vfo == NULL)
{ {
// for non-Icom rigs if there's no set_vfo then we need to set one // for non-Icom rigs if there's no set_vfo then we need to set one
@ -1458,7 +1458,12 @@ int HAMLIB_API rig_open(RIG *rig)
split_t split = RIG_SPLIT_OFF; split_t split = RIG_SPLIT_OFF;
vfo_t tx_vfo = RIG_VFO_NONE; vfo_t tx_vfo = RIG_VFO_NONE;
rig_get_freq(rig, RIG_VFO_B, &freq); rig_get_freq(rig, RIG_VFO_B, &freq);
rig_get_split_vfo(rig, RIG_VFO_RX, &split, &tx_vfo); // 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_debug(RIG_DEBUG_VERBOSE, "%s(%d): Current split=%d, tx_vfo=%s\n", __func__, rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Current split=%d, tx_vfo=%s\n", __func__,
__LINE__, split, rig_strvfo(tx_vfo)); __LINE__, split, rig_strvfo(tx_vfo));
rmode_t mode; rmode_t mode;
@ -3004,27 +3009,6 @@ int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo)
if (curr_vfo == vfo) { RETURNFUNC(RIG_OK); } if (curr_vfo == vfo) { RETURNFUNC(RIG_OK); }
} }
#if 0 // removing this check 20210801 -- should be mapped already
// make sure we are asking for a VFO that the rig actually has
if ((vfo == RIG_VFO_A || vfo == RIG_VFO_B) && !VFO_HAS_A_B)
{
rig_debug(RIG_DEBUG_ERR, "%s: rig does not have %s\n", __func__,
rig_strvfo(vfo));
ELAPSED2;
RETURNFUNC(-RIG_EINVAL);
}
if ((vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB) && !VFO_HAS_MAIN_SUB)
{
rig_debug(RIG_DEBUG_ERR, "%s: rig does not have %s\n", __func__,
rig_strvfo(vfo));
ELAPSED2;
RETURNFUNC(-RIG_EINVAL);
}
#endif
vfo = vfo_fixup(rig, vfo, rig->state.cache.split); vfo = vfo_fixup(rig, vfo, rig->state.cache.split);
caps = rig->caps; caps = rig->caps;
@ -4304,10 +4288,13 @@ int HAMLIB_API rig_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs)
int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
{ {
const struct rig_caps *caps; const struct rig_caps *caps;
const struct rig_state *rs;
int retcode, rc2; int retcode, rc2;
vfo_t curr_vfo, tx_vfo; vfo_t curr_vfo, tx_vfo;
freq_t tfreq = 0; freq_t tfreq = 0;
ENTERFUNC2;
if (CHECK_RIG_ARG(rig)) if (CHECK_RIG_ARG(rig))
{ {
rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n",__func__); rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n",__func__);
@ -4321,17 +4308,26 @@ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo), tx_freq); rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo), tx_freq);
caps = rig->caps; caps = rig->caps;
rs = &rig->state;
/* Use previously setup TxVFO */ // Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
if (vfo == RIG_VFO_CURR || vfo == RIG_VFO_TX) tx_vfo = rs->tx_vfo;
if (rs->cache.split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
{ {
tx_vfo = rig->state.tx_vfo; // Turn split on if not enabled already
} retcode = rig_set_split_vfo(rig, rs->current_vfo, RIG_SPLIT_ON, vfo_fixup(rig, RIG_VFO_OTHER, RIG_SPLIT_OFF));
else if (retcode != RIG_OK)
{ {
tx_vfo = vfo_fixup(rig, vfo, rig->state.cache.split); rig_debug(RIG_DEBUG_ERR, "%s: error turning split on: result=%d\n", __func__, retcode);
ELAPSED2;
RETURNFUNC2(retcode);
}
} }
// TX VFO may change after enabling split
tx_vfo = rs->tx_vfo;
rig_get_freq(rig, tx_vfo, &tfreq); rig_get_freq(rig, tx_vfo, &tfreq);
if (tfreq == tx_freq) if (tfreq == tx_freq)
@ -4341,25 +4337,21 @@ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
RETURNFUNC2(RIG_OK); RETURNFUNC2(RIG_OK);
} }
if (caps->set_split_freq // Use set_split_freq directly if implemented and frequency is targetable
&& (vfo == RIG_VFO_CURR if (caps->set_split_freq && (caps->targetable_vfo & RIG_TARGETABLE_FREQ))
|| vfo == RIG_VFO_TX
|| tx_vfo == rig->state.current_vfo
|| (caps->targetable_vfo & RIG_TARGETABLE_FREQ)))
{ {
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->set_split_freq(rig, vfo, tx_freq); retcode = caps->set_split_freq(rig, tx_vfo, tx_freq);
ELAPSED2; ELAPSED2;
if (retcode == RIG_OK)
{
rig_set_cache_freq(rig, tx_vfo, tx_freq);
}
RETURNFUNC2(retcode); RETURNFUNC2(retcode);
} }
vfo = vfo_fixup(rig, vfo, rig->state.cache.split); // Alternatively, use set_freq if frequency is targetable
if (caps->set_freq && (caps->targetable_vfo & RIG_TARGETABLE_FREQ))
/* Assisted mode */
curr_vfo = rig->state.current_vfo;
if (caps->set_freq)
{ {
int retry = 3; int retry = 3;
@ -4368,7 +4360,10 @@ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = rig_set_freq(rig, tx_vfo, tx_freq); retcode = rig_set_freq(rig, tx_vfo, tx_freq);
if (retcode != RIG_OK) { RETURNFUNC(retcode); } if (retcode != RIG_OK)
{
RETURNFUNC(retcode);
}
#if 0 // this verification seems to be causing bad behavior on some rigs #if 0 // this verification seems to be causing bad behavior on some rigs
retcode = rig_get_freq(rig, tx_vfo, &tfreq); retcode = rig_get_freq(rig, tx_vfo, &tfreq);
@ -4382,6 +4377,10 @@ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
RETURNFUNC2(retcode); RETURNFUNC2(retcode);
} }
// Assisted mode: Swap VFOs and try either set_split_freq or set_freq
curr_vfo = rs->current_vfo;
vfo = vfo_fixup(rig, vfo, rs->cache.split);
if (caps->set_vfo) if (caps->set_vfo)
{ {
HAMLIB_TRACE; HAMLIB_TRACE;
@ -4412,19 +4411,22 @@ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
{ {
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->set_split_freq(rig, vfo, tx_freq); retcode = caps->set_split_freq(rig, vfo, tx_freq);
//rig_get_freq(rig, vfo, &tfreq);
} }
else else
{ {
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = rig_set_freq(rig, RIG_VFO_CURR, tx_freq); retcode = rig_set_freq(rig, RIG_VFO_CURR, tx_freq);
//rig_get_freq(rig, vfo, &tfreq);
} }
tfreq = tx_freq; tfreq = tx_freq;
} }
while (tfreq != tx_freq && retry-- > 0 && retcode == RIG_OK); while (tfreq != tx_freq && retry-- > 0 && retcode == RIG_OK);
if (retcode == RIG_OK)
{
rig_set_cache_freq(rig, tx_vfo, tx_freq);
}
/* try and revert even if we had an error above */ /* try and revert even if we had an error above */
if (caps->set_vfo) if (caps->set_vfo)
{ {
@ -4469,6 +4471,7 @@ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
int HAMLIB_API rig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) int HAMLIB_API rig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
{ {
const struct rig_caps *caps; const struct rig_caps *caps;
const struct rig_state *rs;
int retcode = -RIG_EPROTO, rc2; int retcode = -RIG_EPROTO, rc2;
vfo_t tx_vfo; vfo_t tx_vfo;
@ -4487,42 +4490,48 @@ int HAMLIB_API rig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
RETURNFUNC(-RIG_EINVAL); RETURNFUNC(-RIG_EINVAL);
} }
vfo = vfo_fixup(rig, vfo, rig->state.cache.split);
caps = rig->caps; caps = rig->caps;
rs = &rig->state;
if (caps->get_split_freq // Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
&& (vfo == RIG_VFO_CURR tx_vfo = rs->tx_vfo;
|| vfo == RIG_VFO_TX
|| vfo == rig->state.current_vfo)) if (rs->cache.split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
{
// Split frequency not available if split is off
*tx_freq = 0;
ELAPSED2;
RETURNFUNC(RIG_OK);
}
// Use get_split_freq directly if implemented and frequency is targetable
if (caps->get_split_freq && (caps->targetable_vfo & RIG_TARGETABLE_FREQ))
{ {
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->get_split_freq(rig, vfo, tx_freq); retcode = caps->get_split_freq(rig, tx_vfo, tx_freq);
ELAPSED2; ELAPSED2;
if (retcode == RIG_OK)
{
rig_set_cache_freq(rig, tx_vfo, *tx_freq);
}
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
/* Assisted mode */ // Alternatively, use get_freq if frequency is targetable
//save_vfo = rig->state.current_vfo;
/* Use previously setup TxVFO */
if (vfo == RIG_VFO_CURR || vfo == RIG_VFO_TX)
{
tx_vfo = rig->state.tx_vfo;
}
else
{
tx_vfo = vfo;
}
if (caps->get_freq && (caps->targetable_vfo & RIG_TARGETABLE_FREQ)) if (caps->get_freq && (caps->targetable_vfo & RIG_TARGETABLE_FREQ))
{ {
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->get_freq(rig, tx_vfo, tx_freq); retcode = caps->get_freq(rig, tx_vfo, tx_freq);
ELAPSED2; ELAPSED2;
if (retcode == RIG_OK)
{
rig_set_cache_freq(rig, tx_vfo, *tx_freq);
}
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
// Assisted mode: Swap VFOs and try either get_split_freq or get_freq
vfo = vfo_fixup(rig, vfo, rs->cache.split);
if (caps->set_vfo) if (caps->set_vfo)
{ {
@ -4566,6 +4575,11 @@ int HAMLIB_API rig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
tx_freq) : -RIG_ENIMPL; tx_freq) : -RIG_ENIMPL;
} }
if (retcode == RIG_OK)
{
rig_set_cache_freq(rig, tx_vfo, *tx_freq);
}
/* try and revert even if we had an error above */ /* try and revert even if we had an error above */
if (caps->set_vfo) if (caps->set_vfo)
{ {
@ -4630,6 +4644,7 @@ int HAMLIB_API rig_set_split_mode(RIG *rig,
pbwidth_t tx_width) pbwidth_t tx_width)
{ {
const struct rig_caps *caps; const struct rig_caps *caps;
const struct rig_state *rs;
int retcode, rc2; int retcode, rc2;
vfo_t curr_vfo, tx_vfo, rx_vfo; vfo_t curr_vfo, tx_vfo, rx_vfo;
@ -4642,10 +4657,30 @@ int HAMLIB_API rig_set_split_mode(RIG *rig,
ELAPSED1; ELAPSED1;
ENTERFUNC; ENTERFUNC;
caps = rig->caps;
rs = &rig->state;
// Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
tx_vfo = rs->tx_vfo;
if (rs->cache.split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
{
// Turn split on if not enabled already
retcode = rig_set_split_vfo(rig, rs->current_vfo, RIG_SPLIT_ON, vfo_fixup(rig, RIG_VFO_OTHER, RIG_SPLIT_OFF));
if (retcode != RIG_OK)
{
rig_debug(RIG_DEBUG_ERR, "%s: error turning split on: result=%d\n", __func__, retcode);
ELAPSED2;
RETURNFUNC(retcode);
}
}
// TX VFO may change after enabling split
tx_vfo = rs->tx_vfo;
// we check both VFOs are in the same tx mode -- then we can ignore // we check both VFOs are in the same tx mode -- then we can ignore
// this could be make more intelligent but this should cover all cases where we can skip this // this could be make more intelligent but this should cover all cases where we can skip this
if (tx_mode == rig->state.cache.modeMainA if (tx_mode == rs->cache.modeMainA && tx_mode == rs->cache.modeMainB)
&& tx_mode == rig->state.cache.modeMainB)
{ {
rig_debug(RIG_DEBUG_TRACE, "%s: mode already %s so no change required\n", rig_debug(RIG_DEBUG_TRACE, "%s: mode already %s so no change required\n",
__func__, rig_strrmode(tx_mode)); __func__, rig_strrmode(tx_mode));
@ -4655,57 +4690,47 @@ int HAMLIB_API rig_set_split_mode(RIG *rig,
else else
{ {
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode %s is different from A=%s and B=%s\n", rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode %s is different from A=%s and B=%s\n",
__func__, rig_strvfo(vfo), rig_strrmode(tx_mode), rig_strrmode(rig->state.cache.modeMainA), __func__, rig_strvfo(vfo), rig_strrmode(tx_mode), rig_strrmode(rs->cache.modeMainA),
rig_strrmode(rig->state.cache.modeMainB)); rig_strrmode(rs->cache.modeMainB));
} }
// do not mess with mode while PTT is on // do not mess with mode while PTT is on
if (rig->state.cache.ptt) if (rs->cache.ptt)
{ {
rig_debug(RIG_DEBUG_VERBOSE, "%s PTT on so set_split_mode ignored\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "%s PTT on so set_split_mode ignored\n", __func__);
ELAPSED2; ELAPSED2;
RETURNFUNC(RIG_OK); RETURNFUNC(RIG_OK);
} }
caps = rig->caps; // Use set_split_mode directly if implemented and mode is targetable
if (caps->set_split_mode)
if (caps->set_split_mode
&& (vfo == RIG_VFO_CURR
|| vfo == RIG_VFO_TX
|| vfo == rig->state.current_vfo
|| rig->caps->rig_model == RIG_MODEL_NETRIGCTL))
{ {
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->set_split_mode(rig, vfo, tx_mode, tx_width); retcode = caps->set_split_mode(rig, tx_vfo, tx_mode, tx_width);
ELAPSED2; ELAPSED2;
if (retcode == RIG_OK)
{
rig_set_cache_mode(rig, tx_vfo, tx_mode, tx_width);
}
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
/* Assisted mode */
curr_vfo = rig->state.current_vfo; curr_vfo = rig->state.current_vfo;
/* Use previously setup TxVFO */
if (vfo == RIG_VFO_CURR || vfo == RIG_VFO_TX
|| rig->state.tx_vfo != RIG_VFO_NONE)
{
HAMLIB_TRACE;
tx_vfo = rig->state.tx_vfo;
}
else
{
HAMLIB_TRACE;
tx_vfo = vfo;
}
rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s, tx_vfo=%s\n", __func__, rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s, tx_vfo=%s\n", __func__,
rig_strvfo(curr_vfo), rig_strvfo(tx_vfo)); rig_strvfo(curr_vfo), rig_strvfo(tx_vfo));
// Alternatively, use set_mode if mode is targetable
if (caps->set_mode && ((caps->targetable_vfo & RIG_TARGETABLE_MODE) if (caps->set_mode && ((caps->targetable_vfo & RIG_TARGETABLE_MODE)
|| (rig->caps->rig_model == RIG_MODEL_NETRIGCTL))) || (rig->caps->rig_model == RIG_MODEL_NETRIGCTL)))
{ {
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->set_mode(rig, tx_vfo, tx_mode, tx_width); retcode = caps->set_mode(rig, tx_vfo, tx_mode, tx_width);
ELAPSED2; ELAPSED2;
if (retcode == RIG_OK)
{
rig_set_cache_mode(rig, tx_vfo, tx_mode, tx_width);
}
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
@ -4725,7 +4750,7 @@ int HAMLIB_API rig_set_split_mode(RIG *rig,
// we will reuse cached mode instead of trying to set mode again // we will reuse cached mode instead of trying to set mode again
if ((tx_vfo & (RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_MAIN_A | RIG_VFO_SUB_A)) if ((tx_vfo & (RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_MAIN_A | RIG_VFO_SUB_A))
&& (tx_mode == rig->state.cache.modeMainA)) && (tx_mode == rs->cache.modeMainA))
{ {
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): VFOA mode=%s already set...ignoring\n", rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): VFOA mode=%s already set...ignoring\n",
__func__, __LINE__, rig_strrmode(tx_mode)); __func__, __LINE__, rig_strrmode(tx_mode));
@ -4733,7 +4758,7 @@ int HAMLIB_API rig_set_split_mode(RIG *rig,
RETURNFUNC(RIG_OK); RETURNFUNC(RIG_OK);
} }
else if ((tx_vfo & (RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_MAIN_B | RIG_VFO_SUB_B)) else if ((tx_vfo & (RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_MAIN_B | RIG_VFO_SUB_B))
&& (tx_mode == rig->state.cache.modeMainB)) && (tx_mode == rs->cache.modeMainB))
{ {
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): VFOB mode=%s already set...ignoring\n", rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): VFOB mode=%s already set...ignoring\n",
__func__, __LINE__, rig_strrmode(tx_mode)); __func__, __LINE__, rig_strrmode(tx_mode));
@ -4751,11 +4776,16 @@ int HAMLIB_API rig_set_split_mode(RIG *rig,
if (caps->rig_model == RIG_MODEL_NETRIGCTL) if (caps->rig_model == RIG_MODEL_NETRIGCTL)
{ {
// special handling for netrigctl to avoid set_vfo // special handling for netrigctl to avoid set_vfo
retcode = caps->set_split_mode(rig, vfo, tx_mode, tx_width); retcode = caps->set_split_mode(rig, tx_vfo, tx_mode, tx_width);
ELAPSED2; ELAPSED2;
if (retcode == RIG_OK)
{
rig_set_cache_mode(rig, tx_vfo, tx_mode, tx_width);
}
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
// Assisted mode: Turn split off, swap VFOs and try either set_split_mode or set_mode
rig_set_split_vfo(rig, rx_vfo, RIG_SPLIT_OFF, rx_vfo); rig_set_split_vfo(rig, rx_vfo, RIG_SPLIT_OFF, rx_vfo);
if (caps->set_vfo) if (caps->set_vfo)
@ -4794,6 +4824,11 @@ int HAMLIB_API rig_set_split_mode(RIG *rig,
tx_width) : -RIG_ENIMPL; tx_width) : -RIG_ENIMPL;
} }
if (retcode == RIG_OK)
{
rig_set_cache_mode(rig, tx_vfo, tx_mode, tx_width);
}
/* try and revert even if we had an error above */ /* try and revert even if we had an error above */
if (caps->set_vfo) if (caps->set_vfo)
{ {
@ -4824,7 +4859,6 @@ int HAMLIB_API rig_set_split_mode(RIG *rig,
} }
#endif #endif
ELAPSED2; ELAPSED2;
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
@ -4853,6 +4887,7 @@ int HAMLIB_API rig_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode,
pbwidth_t *tx_width) pbwidth_t *tx_width)
{ {
const struct rig_caps *caps; const struct rig_caps *caps;
const struct rig_state *rs;
int retcode, rc2; int retcode, rc2;
vfo_t curr_vfo, tx_vfo; vfo_t curr_vfo, tx_vfo;
@ -4872,39 +4907,48 @@ int HAMLIB_API rig_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode,
} }
caps = rig->caps; caps = rig->caps;
rs = &rig->state;
if (caps->get_split_mode // Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
&& (vfo == RIG_VFO_CURR tx_vfo = rs->tx_vfo;
|| vfo == RIG_VFO_TX
|| vfo == rig->state.current_vfo)) if (rs->cache.split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
{
// Split mode and filter width are not available if split is off
*tx_mode = RIG_MODE_NONE;
*tx_width = 0;
ELAPSED2;
RETURNFUNC(RIG_OK);
}
// Use get_split_mode directly if implemented and mode is targetable
if (caps->get_split_mode && (caps->targetable_vfo & RIG_TARGETABLE_MODE))
{ {
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->get_split_mode(rig, vfo, tx_mode, tx_width); retcode = caps->get_split_mode(rig, tx_vfo, tx_mode, tx_width);
ELAPSED2; ELAPSED2;
if (retcode == RIG_OK)
{
rig_set_cache_mode(rig, tx_vfo, *tx_mode, *tx_width);
}
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
/* Assisted mode */ // Alternatively, use get_mode if mode is targetable
curr_vfo = rig->state.current_vfo;
/* Use previously setup TxVFO */
if (vfo == RIG_VFO_CURR || vfo == RIG_VFO_TX)
{
tx_vfo = rig->state.tx_vfo;
}
else
{
tx_vfo = vfo;
}
if (caps->get_mode && (caps->targetable_vfo & RIG_TARGETABLE_MODE)) if (caps->get_mode && (caps->targetable_vfo & RIG_TARGETABLE_MODE))
{ {
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->get_mode(rig, tx_vfo, tx_mode, tx_width); retcode = caps->get_mode(rig, tx_vfo, tx_mode, tx_width);
ELAPSED2; ELAPSED2;
if (retcode == RIG_OK)
{
rig_set_cache_mode(rig, tx_vfo, *tx_mode, *tx_width);
}
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
// Assisted mode: Swap VFOs and try either get_split_mode or get_mode
curr_vfo = rs->current_vfo;
if (caps->set_vfo) if (caps->set_vfo)
{ {
@ -4940,6 +4984,11 @@ int HAMLIB_API rig_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode,
tx_width) : -RIG_ENIMPL; tx_width) : -RIG_ENIMPL;
} }
if (retcode == RIG_OK)
{
rig_set_cache_mode(rig, tx_vfo, *tx_mode, *tx_width);
}
/* try and revert even if we had an error above */ /* try and revert even if we had an error above */
if (caps->set_vfo) if (caps->set_vfo)
{ {
@ -4998,6 +5047,8 @@ int HAMLIB_API rig_set_split_freq_mode(RIG *rig,
pbwidth_t tx_width) pbwidth_t tx_width)
{ {
const struct rig_caps *caps; const struct rig_caps *caps;
const struct rig_state *rs;
vfo_t tx_vfo;
int retcode; int retcode;
if (CHECK_RIG_ARG(rig)) if (CHECK_RIG_ARG(rig))
@ -5010,20 +5061,26 @@ int HAMLIB_API rig_set_split_freq_mode(RIG *rig,
ENTERFUNC; ENTERFUNC;
caps = rig->caps; caps = rig->caps;
rs = &rig->state;
// if split is off we'll turn it on // Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
if (rig->state.cache.split == 0) tx_vfo = rs->tx_vfo;
if (rs->cache.split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
{ {
if (rig->state.current_vfo & (RIG_VFO_A | RIG_VFO_MAIN)) // Turn split on if not enabled already
retcode = rig_set_split_vfo(rig, rs->current_vfo, RIG_SPLIT_ON, vfo_fixup(rig, RIG_VFO_OTHER, RIG_SPLIT_OFF));
if (retcode != RIG_OK)
{ {
rig_set_split_vfo(rig, RIG_VFO_A, 1, RIG_VFO_B); rig_debug(RIG_DEBUG_ERR, "%s: error turning split on: result=%d\n", __func__, retcode);
} ELAPSED2;
else RETURNFUNC(retcode);
{
rig_set_split_vfo(rig, RIG_VFO_B, 1, RIG_VFO_A);
} }
} }
// TX VFO may change after enabling split
tx_vfo = rs->tx_vfo;
vfo = vfo_fixup(rig, RIG_VFO_TX, rig->state.cache.split); // get the TX VFO vfo = vfo_fixup(rig, RIG_VFO_TX, rig->state.cache.split); // get the TX VFO
rig_debug(RIG_DEBUG_VERBOSE, rig_debug(RIG_DEBUG_VERBOSE,
"%s: vfo=%s, tx_freq=%.0f, tx_mode=%s, tx_width=%d\n", __func__, "%s: vfo=%s, tx_freq=%.0f, tx_mode=%s, tx_width=%d\n", __func__,
@ -5038,13 +5095,13 @@ int HAMLIB_API rig_set_split_freq_mode(RIG *rig,
#endif #endif
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->set_split_freq_mode(rig, vfo, tx_freq, tx_mode, tx_width); retcode = caps->set_split_freq_mode(rig, tx_vfo, tx_freq, tx_mode, tx_width);
#if 0 // this verification seems to be causing bad behavior on some rigs #if 0 // this verification seems to be causing bad behavior on some rigs
// we query freq after set to ensure it really gets done // we query freq after set to ensure it really gets done
do do
{ {
retcode = caps->set_split_freq_mode(rig, vfo, tx_freq, tx_mode, tx_width); retcode = caps->set_split_freq_mode(rig, tx_vfo, tx_freq, tx_mode, tx_width);
retcode2 = rig_get_split_freq(rig, vfo, &tfreq); retcode2 = rig_get_split_freq(rig, vfo, &tfreq);
if (tfreq != tx_freq) if (tfreq != tx_freq)
@ -5066,6 +5123,11 @@ int HAMLIB_API rig_set_split_freq_mode(RIG *rig,
#endif #endif
ELAPSED2; ELAPSED2;
if (retcode == RIG_OK)
{
rig_set_cache_freq(rig, tx_vfo, tx_freq);
rig_set_cache_mode(rig, tx_vfo, tx_mode, tx_width);
}
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
else else
@ -5119,6 +5181,8 @@ int HAMLIB_API rig_get_split_freq_mode(RIG *rig,
pbwidth_t *tx_width) pbwidth_t *tx_width)
{ {
const struct rig_caps *caps; const struct rig_caps *caps;
const struct rig_state *rs;
vfo_t tx_vfo;
int retcode; int retcode;
if (CHECK_RIG_ARG(rig)) if (CHECK_RIG_ARG(rig))
@ -5137,11 +5201,30 @@ int HAMLIB_API rig_get_split_freq_mode(RIG *rig,
} }
caps = rig->caps; caps = rig->caps;
rs = &rig->state;
// Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
tx_vfo = rs->tx_vfo;
if (rs->cache.split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
{
// Split frequency, mode and filter width are not available if split is off
*tx_freq = 0;
*tx_mode = RIG_MODE_NONE;
*tx_width = 0;
ELAPSED2;
RETURNFUNC(RIG_OK);
}
if (caps->get_split_freq_mode) if (caps->get_split_freq_mode)
{ {
retcode = caps->get_split_freq_mode(rig, vfo, tx_freq, tx_mode, tx_width); retcode = caps->get_split_freq_mode(rig, tx_vfo, tx_freq, tx_mode, tx_width);
ELAPSED2; ELAPSED2;
if (retcode == RIG_OK)
{
rig_set_cache_freq(rig, tx_vfo, *tx_freq);
rig_set_cache_mode(rig, tx_vfo, *tx_mode, *tx_width);
}
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
@ -5181,6 +5264,7 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
{ {
const struct rig_caps *caps; const struct rig_caps *caps;
int retcode; int retcode;
struct rig_state *rs;
vfo_t curr_vfo; vfo_t curr_vfo;
if (CHECK_RIG_ARG(rig)) if (CHECK_RIG_ARG(rig))
@ -5196,6 +5280,7 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
rig_strvfo(rx_vfo), split, rig_strvfo(tx_vfo), rig->state.cache.split); rig_strvfo(rx_vfo), split, rig_strvfo(tx_vfo), rig->state.cache.split);
caps = rig->caps; caps = rig->caps;
rs = &rig->state;
if (caps->set_split_vfo == NULL) if (caps->set_split_vfo == NULL)
{ {
@ -5203,7 +5288,7 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
RETURNFUNC(-RIG_ENAVAIL); RETURNFUNC(-RIG_ENAVAIL);
} }
if (rig->state.cache.ptt) if (rs->cache.ptt)
{ {
rig_debug(RIG_DEBUG_WARN, "%s: cannot execute when PTT is on\n", __func__); rig_debug(RIG_DEBUG_WARN, "%s: cannot execute when PTT is on\n", __func__);
ELAPSED2; ELAPSED2;
@ -5211,7 +5296,7 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
} }
// We fix up vfos for non-satmode rigs only // We fix up vfos for non-satmode rigs only
if (rig->caps->has_get_func & RIG_FUNC_SATMODE) 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", 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)); __func__, rig_strvfo(rx_vfo), rig_strvfo(tx_vfo));
@ -5220,21 +5305,25 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
{ {
switch (tx_vfo) switch (tx_vfo)
{ {
case RIG_VFO_MAIN: rx_vfo = split == 1 ? RIG_VFO_SUB : RIG_VFO_MAIN; break; case RIG_VFO_MAIN:
rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_SUB : RIG_VFO_MAIN;
break;
case RIG_VFO_A: rx_vfo = split == 1 ? RIG_VFO_B : RIG_VFO_A; 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 == 1 ? RIG_VFO_MAIN : RIG_VFO_SUB; 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 == 1 ? RIG_VFO_A : RIG_VFO_B; break; case RIG_VFO_B:
rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_A : RIG_VFO_B;
break;
} }
//rig->state.cache.split = split; // this gets set later
//rig->state.cache.split_vfo = tx_vfo;
rx_vfo = vfo_fixup(rig, rx_vfo, split); rx_vfo = vfo_fixup(rig, rx_vfo, split);
tx_vfo = vfo_fixup(rig, tx_vfo, split); tx_vfo = vfo_fixup(rig, tx_vfo, split);
rig->state.rx_vfo = rx_vfo;
rig->state.tx_vfo = tx_vfo;
rig_debug(RIG_DEBUG_VERBOSE, "%s: final rxvfo=%s, txvfo=%s, split=%d\n", rig_debug(RIG_DEBUG_VERBOSE, "%s: final rxvfo=%s, txvfo=%s, split=%d\n",
__func__, __func__,
rig_strvfo(rx_vfo), rig_strvfo(tx_vfo), split); rig_strvfo(rx_vfo), rig_strvfo(tx_vfo), split);
@ -5244,14 +5333,14 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
HAMLIB_TRACE; HAMLIB_TRACE;
if ((!(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) if ((!(caps->targetable_vfo & RIG_TARGETABLE_FREQ))
&& (!(rig->caps->rig_model == RIG_MODEL_NETRIGCTL))) && (!(caps->rig_model == RIG_MODEL_NETRIGCTL)))
rig_set_vfo(rig, rx_vfo); rig_set_vfo(rig, rx_vfo);
if (rx_vfo == RIG_VFO_CURR // Check if RX VFO is the currently active VFO and we don't need to change the VFO
|| rx_vfo == rig->state.current_vfo) if (rx_vfo == RIG_VFO_CURR || rx_vfo == rs->current_vfo)
{ {
// for non-targetable VFOs we will not set split again // for non-targetable VFOs we will not set split again
if (rig->state.cache.split == split && rig->state.cache.split_vfo == tx_vfo) 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 set...ignoring\n", __func__,
__LINE__); __LINE__);
@ -5263,23 +5352,27 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
if (retcode == RIG_OK) if (retcode == RIG_OK)
{ {
rig->state.tx_vfo = tx_vfo; // 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;
} }
rig->state.cache.split = split; elapsed_ms(&rs->cache.time_split, HAMLIB_ELAPSED_SET);
rig->state.cache.split_vfo = tx_vfo;
elapsed_ms(&rig->state.cache.time_split, HAMLIB_ELAPSED_SET);
ELAPSED2; ELAPSED2;
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
// RX VFO change required
if (!caps->set_vfo) if (!caps->set_vfo)
{ {
ELAPSED2; ELAPSED2;
RETURNFUNC(-RIG_ENAVAIL); RETURNFUNC(-RIG_ENAVAIL);
} }
curr_vfo = rig->state.current_vfo; curr_vfo = rs->current_vfo;
HAMLIB_TRACE; HAMLIB_TRACE;
if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ))
@ -5296,7 +5389,7 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->set_split_vfo(rig, rx_vfo, split, tx_vfo); retcode = caps->set_split_vfo(rig, rx_vfo, split, tx_vfo);
/* try and revert even if we had an error above */ /* try and revert VFO change even if we had an error above */
if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ))
{ {
int rc2 = caps->set_vfo(rig, curr_vfo); int rc2 = caps->set_vfo(rig, curr_vfo);
@ -5310,12 +5403,14 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
if (retcode == RIG_OK) if (retcode == RIG_OK)
{ {
rig->state.tx_vfo = tx_vfo; // 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;
} }
rig->state.cache.split = split; elapsed_ms(&rs->cache.time_split, HAMLIB_ELAPSED_SET);
rig->state.cache.split_vfo = tx_vfo;
elapsed_ms(&rig->state.cache.time_split, HAMLIB_ELAPSED_SET);
ELAPSED2; ELAPSED2;
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
@ -5342,14 +5437,8 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
vfo_t *tx_vfo) vfo_t *tx_vfo)
{ {
const struct rig_caps *caps; const struct rig_caps *caps;
#if 0 struct rig_state *rs;
int retcode, rc2;
#else
int retcode; int retcode;
#endif
#if 0
vfo_t curr_vfo;
#endif
int cache_ms; int cache_ms;
if (CHECK_RIG_ARG(rig)) if (CHECK_RIG_ARG(rig))
@ -5370,12 +5459,13 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
} }
caps = rig->caps; caps = rig->caps;
rs = &rig->state;
if (caps->get_split_vfo == NULL) if (caps->get_split_vfo == NULL)
{ {
// if we can't get the vfo we will return whatever we have cached // if we can't get the vfo we will return whatever we have cached
*split = rig->state.cache.split; *split = rs->cache.split;
*tx_vfo = rig->state.cache.split_vfo; *tx_vfo = rs->cache.split_vfo;
rig_debug(RIG_DEBUG_VERBOSE, rig_debug(RIG_DEBUG_VERBOSE,
"%s: no get_split_vfo so returning split=%d, tx_vfo=%s\n", __func__, *split, "%s: no get_split_vfo so returning split=%d, tx_vfo=%s\n", __func__, *split,
rig_strvfo(*tx_vfo)); rig_strvfo(*tx_vfo));
@ -5386,10 +5476,10 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
cache_ms = elapsed_ms(&rig->state.cache.time_split, HAMLIB_ELAPSED_GET); cache_ms = elapsed_ms(&rig->state.cache.time_split, HAMLIB_ELAPSED_GET);
rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms); rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms);
if (cache_ms < rig->state.cache.timeout_ms) if (cache_ms < rs->cache.timeout_ms)
{ {
*split = rig->state.cache.split; *split = rs->cache.split;
*tx_vfo = rig->state.cache.split_vfo; *tx_vfo = rs->cache.split_vfo;
rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms, split=%d, tx_vfo=%s\n", rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms, split=%d, tx_vfo=%s\n",
__func__, cache_ms, *split, rig_strvfo(*tx_vfo)); __func__, cache_ms, *split, rig_strvfo(*tx_vfo));
ELAPSED2; ELAPSED2;
@ -5400,66 +5490,17 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms\n", __func__, cache_ms); rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms\n", __func__, cache_ms);
} }
/* overridden by backend at will */
*tx_vfo = rig->state.tx_vfo;
if ((vfo == RIG_VFO_CURR) || (vfo == rig->state.current_vfo))
{
HAMLIB_TRACE;
//retcode = RIG_OK;
//if (rig->caps->rig_model != RIG_MODEL_NETRIGCTL)
{
// rigctld doesn't like nested calls
retcode = caps->get_split_vfo(rig, vfo, split, tx_vfo);
rig->state.cache.split = *split;
rig->state.cache.split_vfo = *tx_vfo;
elapsed_ms(&rig->state.cache.time_split, HAMLIB_ELAPSED_SET);
rig_debug(RIG_DEBUG_TRACE, "%s: cache.split=%d\n", __func__,
rig->state.cache.split);
}
ELAPSED2;
RETURNFUNC(retcode);
}
if (!caps->set_vfo)
{
ELAPSED2;
RETURNFUNC(-RIG_ENAVAIL);
}
#if 0 // why were we doing this? Shouldn't need to set_vfo to figure out tx_vfo
curr_vfo = rig->state.current_vfo;
retcode = caps->set_vfo(rig, vfo);
if (retcode != RIG_OK)
{
ELAPSED2;
RETURNFUNC(retcode);
}
#endif
HAMLIB_TRACE; HAMLIB_TRACE;
retcode = caps->get_split_vfo(rig, vfo, split, tx_vfo); retcode = caps->get_split_vfo(rig, vfo, split, tx_vfo);
#if 0 // see above
/* try and revert even if we had an error above */
rc2 = caps->set_vfo(rig, curr_vfo);
if (RIG_OK == retcode) if (retcode == RIG_OK)
{ {
/* return the first error code */ // Only update cache on success
retcode = rc2; rs->cache.split = *split;
} rs->cache.split_vfo = *tx_vfo;
elapsed_ms(&rs->cache.time_split, HAMLIB_ELAPSED_SET);
#endif
if (retcode == RIG_OK) // only update cache on success
{
rig->state.cache.split = *split;
rig->state.cache.split_vfo = *tx_vfo;
elapsed_ms(&rig->state.cache.time_split, HAMLIB_ELAPSED_SET);
rig_debug(RIG_DEBUG_TRACE, "%s(%d): cache.split=%d\n", __func__, __LINE__, rig_debug(RIG_DEBUG_TRACE, "%s(%d): cache.split=%d\n", __func__, __LINE__,
rig->state.cache.split); rs->cache.split);
} }
ELAPSED2; ELAPSED2;

Wyświetl plik

@ -576,11 +576,10 @@ int rig_sprintf_parm_gran(char *str, int nlen, setting_t parm,
{ {
if (gran[i].step.s) if (gran[i].step.s)
{ {
rig_debug(RIG_DEBUG_ERR, "%s: BAND_SELECT?\n", __func__); len += sprintf(str + len,
len += sprintf(str + len, "%s(%s) ",
"%s(%s) ", ms,
ms, gran[i].step.s);
gran[i].step.s);
} }
} }
else else

Wyświetl plik

@ -247,6 +247,23 @@ int dumpcaps(RIG *rig, FILE *fout)
"Has targetable VFO: %s\n", "Has targetable VFO: %s\n",
caps->targetable_vfo ? "Y" : "N"); caps->targetable_vfo ? "Y" : "N");
fprintf(fout, "Targetable features:");
if (caps->targetable_vfo & RIG_TARGETABLE_FREQ) { fprintf(fout, " FREQ"); }
if (caps->targetable_vfo & RIG_TARGETABLE_MODE) { fprintf(fout, " MODE"); }
if (caps->targetable_vfo & RIG_TARGETABLE_TONE) { fprintf(fout, " TONE"); }
if (caps->targetable_vfo & RIG_TARGETABLE_FUNC) { fprintf(fout, " FUNC"); }
if (caps->targetable_vfo & RIG_TARGETABLE_LEVEL) { fprintf(fout, " LEVEL"); }
if (caps->targetable_vfo & RIG_TARGETABLE_RITXIT) { fprintf(fout, " RITXIT"); }
if (caps->targetable_vfo & RIG_TARGETABLE_PTT) { fprintf(fout, " PTT"); }
if (caps->targetable_vfo & RIG_TARGETABLE_MEM) { fprintf(fout, " MEM"); }
if (caps->targetable_vfo & RIG_TARGETABLE_BANK) { fprintf(fout, " BANK"); }
if (caps->targetable_vfo & RIG_TARGETABLE_ANT) { fprintf(fout, " ANT"); }
if (caps->targetable_vfo & RIG_TARGETABLE_ROOFING) { fprintf(fout, " ROOFING"); }
if (caps->targetable_vfo & RIG_TARGETABLE_SPECTRUM) { fprintf(fout, " SPECTRUM"); }
if (caps->targetable_vfo & RIG_TARGETABLE_BAND) { fprintf(fout, " BAND"); }
if (caps->targetable_vfo == 0) { fprintf(fout, " None"); }
fprintf(fout, "\n");
fprintf(fout, fprintf(fout,
"Has async data support: %s\n", "Has async data support: %s\n",
caps->async_data_supported ? "Y" : "N"); caps->async_data_supported ? "Y" : "N");