kopia lustrzana https://github.com/Hamlib/Hamlib
Implement rig_{set,get}_split_freq_mode() for IC-756 series.
This implementation reduces the number of VFO excahnges or sets to a minimum when setting the TX VFO frequency and mode together. This also includes a much smarter implementation of the logic used when the new config option 'no_xchg' is enabled. Now it is able to accurately determine the original VFO selected and leaves the sequences with the same VFO selected. There is one corner case when both VFOs are identical (frequency, mode and width) at the start where it has to take a guess as to the selected originally VFO (Icom CAT protocol has no command to elicit this information). In that case it guesses as the last VFO selected using Hamlib. Applications can gain absolute certainty by setting the VFO themselves prior to using the rig_{set,get}_{split,}_{freq,mode,freq_mode}() function series. This now gives seamless TX VFO configuration without any relay clattering or TX/RX audio glitches.Hamlib-3.1
rodzic
e5aa3639ed
commit
e593afef95
|
@ -241,6 +241,8 @@ const struct rig_caps ic756_caps = {
|
|||
.get_split_freq = icom_get_split_freq,
|
||||
.set_split_mode = icom_set_split_mode,
|
||||
.get_split_mode = icom_get_split_mode,
|
||||
.set_split_freq_mode = icom_set_split_freq_mode,
|
||||
.get_split_freq_mode = icom_get_split_freq_mode,
|
||||
.set_split_vfo = icom_set_split_vfo,
|
||||
.get_split_vfo = icom_mem_get_split_vfo,
|
||||
|
||||
|
@ -390,6 +392,8 @@ const struct rig_caps ic756pro_caps = {
|
|||
.get_split_freq = icom_get_split_freq,
|
||||
.set_split_mode = icom_set_split_mode,
|
||||
.get_split_mode = icom_get_split_mode,
|
||||
.set_split_freq_mode = icom_set_split_freq_mode,
|
||||
.get_split_freq_mode = icom_get_split_freq_mode,
|
||||
.set_split_vfo = icom_set_split_vfo,
|
||||
.get_split_vfo = icom_mem_get_split_vfo,
|
||||
|
||||
|
@ -596,6 +600,8 @@ const struct rig_caps ic756pro2_caps = {
|
|||
.get_split_freq = icom_get_split_freq,
|
||||
.set_split_mode = icom_set_split_mode,
|
||||
.get_split_mode = icom_get_split_mode,
|
||||
.set_split_freq_mode = icom_set_split_freq_mode,
|
||||
.get_split_freq_mode = icom_get_split_freq_mode,
|
||||
.set_split_vfo = icom_set_split_vfo,
|
||||
.get_split_vfo = icom_mem_get_split_vfo,
|
||||
|
||||
|
@ -933,6 +939,8 @@ const struct rig_caps ic756pro3_caps = {
|
|||
.get_split_freq = icom_get_split_freq,
|
||||
.set_split_mode = icom_set_split_mode,
|
||||
.get_split_mode = icom_get_split_mode,
|
||||
.set_split_freq_mode = icom_set_split_freq_mode,
|
||||
.get_split_freq_mode = icom_get_split_freq_mode,
|
||||
.set_split_vfo = icom_set_split_vfo,
|
||||
.get_split_vfo = icom_mem_get_split_vfo,
|
||||
|
||||
|
|
326
icom/icom.c
326
icom/icom.c
|
@ -1700,6 +1700,26 @@ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* strategy here is to attempt to leave the original VFO selected
|
||||
even though Icom provides no way to tell what the current VFO is. So
|
||||
we read current frequency and mode and compare with SUB/B, this
|
||||
gives up a clue so long as both VFOs are not the same frequency and
|
||||
mode (and we don't really care if they are, the price for not using
|
||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
||||
rig relays). */
|
||||
|
||||
freq_t orig_freq, second_freq;
|
||||
rmode_t orig_mode, second_mode;
|
||||
pbwidth_t orig_width, second_width;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &orig_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &orig_mode, &orig_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = get_split_vfos(rig, &rx_vfo, &tx_vfo);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
@ -1708,13 +1728,28 @@ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
|
|||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &second_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &second_mode, &second_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_set_freq(rig, RIG_VFO_CURR, tx_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
if (second_freq != orig_freq || second_mode != orig_mode || second_width != orig_width) {
|
||||
/* RX VFO must have been selected when we started so switch back
|
||||
to it */
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
rig->state.current_vfo = rx_vfo;
|
||||
} else {
|
||||
/* here we don't know the original VFO so we use the last one set
|
||||
by any other command */
|
||||
status = icom_set_vfo (rig, rig->state.current_vfo);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -1752,6 +1787,26 @@ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* strategy here is to attempt to leave the original VFO selected
|
||||
even though Icom provides no way to tell what the current VFO is. So
|
||||
we read current frequency and mode and compare with SUB/B, this
|
||||
gives up a clue so long as both VFOs are not the same frequency and
|
||||
mode (and we don't really care if they are, the price for not using
|
||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
||||
rig relays). */
|
||||
|
||||
freq_t orig_freq;
|
||||
rmode_t orig_mode, second_mode;
|
||||
pbwidth_t orig_width, second_width;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &orig_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &orig_mode, &orig_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = get_split_vfos(rig, &rx_vfo, &tx_vfo);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
@ -1764,10 +1819,20 @@ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
|
|||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &second_mode, &second_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
if (*tx_freq != orig_freq || second_mode != orig_mode || second_width != orig_width) {
|
||||
/* RX VFO must have been selected when we started so switch back
|
||||
to it */
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
} else {
|
||||
/* here we don't know the original VFO so we use the last one set
|
||||
by any other command */
|
||||
status = icom_set_vfo (rig, rig->state.current_vfo);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1804,6 +1869,26 @@ int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* strategy here is to attempt to leave the original VFO selected
|
||||
even though Icom provides no way to tell what the current VFO is. So
|
||||
we read current frequency and mode and compare with SUB/B, this
|
||||
gives up a clue so long as both VFOs are not the same frequency and
|
||||
mode (and we don't really care if they are, the price for not using
|
||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
||||
rig relays). */
|
||||
|
||||
freq_t orig_freq, second_freq;
|
||||
rmode_t orig_mode, second_mode;
|
||||
pbwidth_t orig_width, second_width;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &orig_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &orig_mode, &orig_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = get_split_vfos(rig, &rx_vfo, &tx_vfo);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
@ -1812,13 +1897,27 @@ int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width
|
|||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &second_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &second_mode, &second_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
if (second_freq != orig_freq || second_mode != orig_mode || second_width != orig_width) {
|
||||
/* RX VFO must have been selected when we started so switch back
|
||||
to it */
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
} else {
|
||||
/* here we don't know the original VFO so we use the last one set
|
||||
by any other command */
|
||||
status = icom_set_vfo (rig, rig->state.current_vfo);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -1857,6 +1956,26 @@ int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_wid
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* strategy here is to attempt to leave the original VFO selected
|
||||
even though Icom provides no way to tell what the current VFO is. So
|
||||
we read current frequency and mode and compare with SUB/B, this
|
||||
gives up a clue so long as both VFOs are not the same frequency and
|
||||
mode (and we don't really care if they are, the price for not using
|
||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
||||
rig relays). */
|
||||
|
||||
freq_t orig_freq, second_freq;
|
||||
rmode_t orig_mode;
|
||||
pbwidth_t orig_width;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &orig_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &orig_mode, &orig_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = get_split_vfos(rig, &rx_vfo, &tx_vfo);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
@ -1865,14 +1984,205 @@ int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_wid
|
|||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &second_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
if (second_freq != orig_freq || *tx_mode != orig_mode || *tx_width != orig_width) {
|
||||
/* RX VFO must have been selected when we started so switch back
|
||||
to it */
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
} else {
|
||||
/* here we don't know the original VFO so we use the last one set
|
||||
by any other command */
|
||||
status = icom_set_vfo (rig, rig->state.current_vfo);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* icom_set_split_freq_mode
|
||||
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
||||
* icom_set_vfo,icom_set_mode works for this rig
|
||||
* FIXME: status
|
||||
*/
|
||||
int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mode, pbwidth_t tx_width)
|
||||
{
|
||||
int status;
|
||||
vfo_t rx_vfo, tx_vfo;
|
||||
struct icom_priv_data *priv;
|
||||
struct rig_state *rs;
|
||||
|
||||
rs = &rig->state;
|
||||
priv = (struct icom_priv_data*)rs->priv;
|
||||
|
||||
/* This method works also in memory mode(RIG_VFO_MEM) */
|
||||
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig_set_freq(rig, RIG_VFO_CURR, tx_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* strategy here is to attempt to leave the original VFO selected
|
||||
even though Icom provides no way to tell what the current VFO is. So
|
||||
we read current frequency and mode and compare with SUB/B, this
|
||||
gives up a clue so long as both VFOs are not the same frequency and
|
||||
mode (and we don't really care if they are, the price for not using
|
||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
||||
rig relays). */
|
||||
|
||||
freq_t orig_freq, second_freq;
|
||||
rmode_t orig_mode, second_mode;
|
||||
pbwidth_t orig_width, second_width;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &orig_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &orig_mode, &orig_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = get_split_vfos(rig, &rx_vfo, &tx_vfo);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_set_vfo(rig, tx_vfo);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &second_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &second_mode, &second_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig_set_freq(rig, RIG_VFO_CURR, tx_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
if (second_freq != orig_freq || second_mode != orig_mode || second_width != orig_width) {
|
||||
/* RX VFO must have been selected when we started so switch back
|
||||
to it */
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
} else {
|
||||
/* here we don't know the original VFO so we use the last one set
|
||||
by any other command */
|
||||
status = icom_set_vfo (rig, rig->state.current_vfo);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* icom_get_split_freq_mode
|
||||
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
||||
* rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL
|
||||
* icom_set_vfo,icom_get_mode works for this rig
|
||||
* FIXME: status
|
||||
*/
|
||||
int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq, rmode_t *tx_mode, pbwidth_t *tx_width)
|
||||
{
|
||||
int status;
|
||||
vfo_t rx_vfo, tx_vfo;
|
||||
struct icom_priv_data *priv;
|
||||
struct rig_state *rs;
|
||||
|
||||
rs = &rig->state;
|
||||
priv = (struct icom_priv_data*)rs->priv;
|
||||
|
||||
/* This method works also in memory mode(RIG_VFO_MEM) */
|
||||
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig_get_freq(rig, RIG_VFO_CURR, tx_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* strategy here is to attempt to leave the original VFO selected
|
||||
even though Icom provides no way to tell what the current VFO is. So
|
||||
we read current frequency and mode and compare with SUB/B, this
|
||||
gives up a clue so long as both VFOs are not the same frequency and
|
||||
mode (and we don't really care if they are, the price for not using
|
||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
||||
rig relays). */
|
||||
|
||||
freq_t orig_freq;
|
||||
rmode_t orig_mode;
|
||||
pbwidth_t orig_width;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, &orig_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, &orig_mode, &orig_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = get_split_vfos(rig, &rx_vfo, &tx_vfo);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_set_vfo(rig, tx_vfo);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = icom_get_freq(rig, RIG_VFO_CURR, tx_freq);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
status = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
||||
if (status != RIG_OK)
|
||||
return status;
|
||||
|
||||
if (*tx_freq != orig_freq || *tx_mode != orig_mode || *tx_width != orig_width) {
|
||||
/* RX VFO must have been selected when we started so switch back
|
||||
to it */
|
||||
status = icom_set_vfo(rig, rx_vfo);
|
||||
} else {
|
||||
/* here we don't know the original VFO so we use the last one set
|
||||
by any other command */
|
||||
status = icom_set_vfo (rig, rig->state.current_vfo);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,6 +159,8 @@ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq);
|
|||
int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq);
|
||||
int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width);
|
||||
int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width);
|
||||
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_mem_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo);
|
||||
|
|
Ładowanie…
Reference in New Issue