kopia lustrzana https://github.com/Hamlib/Hamlib
Further attempts to simplify and improve Icom CAT for split operating
rodzic
badeb6542d
commit
47a808dcf8
656
icom/icom.c
656
icom/icom.c
|
@ -855,7 +855,6 @@ int icom_set_vfo(RIG *rig, vfo_t vfo)
|
||||||
unsigned char ackbuf[MAXFRAMELEN];
|
unsigned char ackbuf[MAXFRAMELEN];
|
||||||
int ack_len=sizeof(ackbuf), icvfo, retval;
|
int ack_len=sizeof(ackbuf), icvfo, retval;
|
||||||
|
|
||||||
|
|
||||||
if (vfo == RIG_VFO_CURR)
|
if (vfo == RIG_VFO_CURR)
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
|
|
||||||
|
@ -1670,245 +1669,158 @@ static int get_split_vfos(const RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo)
|
||||||
* icom_set_split_freq
|
* icom_set_split_freq
|
||||||
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
||||||
* icom_set_vfo,icom_set_freq works for this rig
|
* icom_set_vfo,icom_set_freq works for this rig
|
||||||
* FIXME: status
|
|
||||||
*
|
*
|
||||||
* Assumes also that the current VFO is the rx VFO.
|
* Assumes also that the current VFO is the rx VFO.
|
||||||
*/
|
*/
|
||||||
int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
|
int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
|
||||||
{
|
{
|
||||||
int status;
|
int rc;
|
||||||
vfo_t rx_vfo, tx_vfo;
|
vfo_t rx_vfo, tx_vfo;
|
||||||
struct icom_priv_data *priv;
|
struct icom_priv_data *priv;
|
||||||
struct rig_state *rs;
|
struct rig_state *rs;
|
||||||
|
unsigned char ackbuf[MAXFRAMELEN];
|
||||||
|
int ack_len=sizeof(ackbuf);
|
||||||
|
|
||||||
rs = &rig->state;
|
rs = &rig->state;
|
||||||
priv = (struct icom_priv_data*)rs->priv;
|
priv = (struct icom_priv_data*)rs->priv;
|
||||||
|
|
||||||
/* This method works also in memory mode(RIG_VFO_MEM) */
|
/* This method works also in memory mode(RIG_VFO_MEM) */
|
||||||
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
||||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
if (status != RIG_OK)
|
if (RIG_OK != (rc = icom_set_freq(rig, RIG_VFO_CURR, tx_freq))) return rc;
|
||||||
return status;
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
|
return rc;
|
||||||
status = icom_set_freq(rig, RIG_VFO_CURR, tx_freq);
|
|
||||||
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
|
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||||
even though Icom provides no way to tell what the current VFO is. So
|
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||||
we read current frequency and mode and compare with SUB/B, this
|
assumptions allow us to deal with the lack of VFO and split
|
||||||
gives up a clue so long as both VFOs are not the same frequency and
|
queries */
|
||||||
mode (and we don't really care if they are, the price for not using
|
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
|
||||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
&& priv->split_on) { /* broken if user changes split on rig :( */
|
||||||
rig relays). */
|
/* VFO A/B style rigs swap VFO on split Tx so we need to disable
|
||||||
|
split for certainty */
|
||||||
freq_t orig_freq, second_freq;
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
rmode_t orig_mode, second_mode;
|
if (ack_len != 1 || ackbuf[0] != ACK) {
|
||||||
pbwidth_t orig_width, second_width;
|
rig_debug(RIG_DEBUG_ERR,"icom_set_split_freq_mode: ack NG (%#.2x), "
|
||||||
|
"len=%d\n", ackbuf[0],ack_len);
|
||||||
status = icom_get_freq(rig, RIG_VFO_CURR, &orig_freq);
|
return -RIG_ERJCTED;
|
||||||
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 = icom_set_freq(rig, RIG_VFO_CURR, tx_freq);
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return status;
|
if (RIG_OK != (rc = get_split_vfos(rig, &rx_vfo, &tx_vfo))) return rc;
|
||||||
|
if (RIG_OK != (rc = icom_set_vfo(rig, tx_vfo))) return rc;
|
||||||
|
if (RIG_OK != (rc = rig_set_freq(rig, RIG_VFO_CURR, tx_freq))) 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)
|
||||||
|
&& priv->split_on) {
|
||||||
|
/* Re-enable split */
|
||||||
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* icom_get_split_freq
|
* icom_get_split_freq
|
||||||
* Assumes rig!=NULL, rig->state.priv!=NULL, rx_freq!=NULL, tx_freq!=NULL
|
* Assumes rig!=NULL, rig->state.priv!=NULL, rx_freq!=NULL, tx_freq!=NULL
|
||||||
* icom_set_vfo,icom_get_freq works for this rig
|
* icom_set_vfo,icom_get_freq works for this rig
|
||||||
* FIXME: status
|
|
||||||
*/
|
*/
|
||||||
int icom_get_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 status;
|
int rc;
|
||||||
vfo_t rx_vfo, tx_vfo;
|
vfo_t rx_vfo, tx_vfo;
|
||||||
struct icom_priv_data *priv;
|
struct icom_priv_data *priv;
|
||||||
struct rig_state *rs;
|
struct rig_state *rs;
|
||||||
|
unsigned char ackbuf[MAXFRAMELEN];
|
||||||
|
int ack_len=sizeof(ackbuf);
|
||||||
|
|
||||||
rs = &rig->state;
|
rs = &rig->state;
|
||||||
priv = (struct icom_priv_data*)rs->priv;
|
priv = (struct icom_priv_data*)rs->priv;
|
||||||
|
|
||||||
/* This method works also in memory mode(RIG_VFO_MEM) */
|
/* This method works also in memory mode(RIG_VFO_MEM) */
|
||||||
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
||||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
if (status != RIG_OK)
|
if (RIG_OK != (rc = icom_get_freq(rig, RIG_VFO_CURR, tx_freq))) return rc;
|
||||||
return status;
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
|
return rc;
|
||||||
status = icom_get_freq(rig, RIG_VFO_CURR, tx_freq);
|
|
||||||
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
|
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||||
even though Icom provides no way to tell what the current VFO is. So
|
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||||
we read current frequency and mode and compare with SUB/B, this
|
assumptions allow us to deal with the lack of VFO and split
|
||||||
gives up a clue so long as both VFOs are not the same frequency and
|
queries */
|
||||||
mode (and we don't really care if they are, the price for not using
|
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
|
||||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
&& priv->split_on) { /* broken if user changes split on rig :( */
|
||||||
rig relays). */
|
/* VFO A/B style rigs swap VFO on split Tx so we need to disable
|
||||||
|
split for certainty */
|
||||||
freq_t orig_freq;
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
rmode_t orig_mode, second_mode;
|
if (ack_len != 1 || ackbuf[0] != ACK) {
|
||||||
pbwidth_t orig_width, second_width;
|
rig_debug(RIG_DEBUG_ERR,"icom_set_split_freq_mode: ack NG (%#.2x), "
|
||||||
|
"len=%d\n", ackbuf[0],ack_len);
|
||||||
status = icom_get_freq(rig, RIG_VFO_CURR, &orig_freq);
|
return -RIG_ERJCTED;
|
||||||
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, &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);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return status;
|
if (RIG_OK != (rc = get_split_vfos(rig, &rx_vfo, &tx_vfo))) return rc;
|
||||||
|
if (RIG_OK != (rc = icom_set_vfo(rig, tx_vfo))) return rc;
|
||||||
|
if (RIG_OK != (rc = icom_get_freq(rig, RIG_VFO_CURR, tx_freq))) 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)
|
||||||
|
&& priv->split_on) {
|
||||||
|
/* Re-enable split */
|
||||||
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* icom_set_split_mode
|
* icom_set_split_mode
|
||||||
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
||||||
* icom_set_vfo,icom_set_mode works for this rig
|
* icom_set_vfo,icom_set_mode works for this rig
|
||||||
* FIXME: status
|
|
||||||
*/
|
*/
|
||||||
int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width)
|
int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width)
|
||||||
{
|
{
|
||||||
int status;
|
int rc;
|
||||||
vfo_t rx_vfo, tx_vfo;
|
vfo_t rx_vfo, tx_vfo;
|
||||||
struct icom_priv_data *priv;
|
struct icom_priv_data *priv;
|
||||||
struct rig_state *rs;
|
struct rig_state *rs;
|
||||||
|
unsigned char ackbuf[MAXFRAMELEN];
|
||||||
|
int ack_len=sizeof(ackbuf);
|
||||||
|
|
||||||
rs = &rig->state;
|
rs = &rig->state;
|
||||||
priv = (struct icom_priv_data*)rs->priv;
|
priv = (struct icom_priv_data*)rs->priv;
|
||||||
|
|
||||||
/* This method works also in memory mode(RIG_VFO_MEM) */
|
/* This method works also in memory mode(RIG_VFO_MEM) */
|
||||||
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
||||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
if (status != RIG_OK)
|
if (RIG_OK != (rc = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) return rc;
|
||||||
return status;
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
|
return rc;
|
||||||
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
|
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||||
even though Icom provides no way to tell what the current VFO is. So
|
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||||
we read current frequency and mode and compare with SUB/B, this
|
assumptions allow us to deal with the lack of VFO and split
|
||||||
gives up a clue so long as both VFOs are not the same frequency and
|
queries */
|
||||||
mode (and we don't really care if they are, the price for not using
|
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
|
||||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
&& priv->split_on) { /* broken if user changes split on rig :( */
|
||||||
rig relays). */
|
/* VFO A/B style rigs swap VFO on split Tx so we need to disable
|
||||||
|
split for certainty */
|
||||||
freq_t orig_freq, second_freq;
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
rmode_t orig_mode, second_mode;
|
if (ack_len != 1 || ackbuf[0] != ACK) {
|
||||||
pbwidth_t orig_width, second_width;
|
rig_debug(RIG_DEBUG_ERR,"icom_set_split_freq_mode: ack NG (%#.2x), "
|
||||||
|
"len=%d\n", ackbuf[0],ack_len);
|
||||||
status = icom_get_freq(rig, RIG_VFO_CURR, &orig_freq);
|
return -RIG_ERJCTED;
|
||||||
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->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);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return status;
|
if (RIG_OK != (rc = get_split_vfos(rig, &rx_vfo, &tx_vfo))) return rc;
|
||||||
|
if (RIG_OK != (rc = icom_set_vfo(rig, tx_vfo))) return rc;
|
||||||
|
if (RIG_OK != (rc = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) 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)
|
||||||
|
&& priv->split_on) {
|
||||||
|
/* Re-enable split */
|
||||||
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1916,257 +1828,102 @@ int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width
|
||||||
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
||||||
* rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL
|
* rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL
|
||||||
* icom_set_vfo,icom_get_mode works for this rig
|
* icom_set_vfo,icom_get_mode works for this rig
|
||||||
* FIXME: status
|
|
||||||
*/
|
*/
|
||||||
int icom_get_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 status;
|
int rc;
|
||||||
vfo_t rx_vfo, tx_vfo;
|
vfo_t rx_vfo, tx_vfo;
|
||||||
struct icom_priv_data *priv;
|
struct icom_priv_data *priv;
|
||||||
struct rig_state *rs;
|
struct rig_state *rs;
|
||||||
|
unsigned char ackbuf[MAXFRAMELEN];
|
||||||
|
int ack_len=sizeof(ackbuf);
|
||||||
|
|
||||||
rs = &rig->state;
|
rs = &rig->state;
|
||||||
priv = (struct icom_priv_data*)rs->priv;
|
priv = (struct icom_priv_data*)rs->priv;
|
||||||
|
|
||||||
/* This method works also in memory mode(RIG_VFO_MEM) */
|
/* This method works also in memory mode(RIG_VFO_MEM) */
|
||||||
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
||||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
if (status != RIG_OK)
|
if (RIG_OK != (rc = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) return rc;
|
||||||
return status;
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
|
return rc;
|
||||||
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
|
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||||
even though Icom provides no way to tell what the current VFO is. So
|
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||||
we read current frequency and mode and compare with SUB/B, this
|
assumptions allow us to deal with the lack of VFO and split
|
||||||
gives up a clue so long as both VFOs are not the same frequency and
|
queries */
|
||||||
mode (and we don't really care if they are, the price for not using
|
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
|
||||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
&& priv->split_on) { /* broken if user changes split on rig :( */
|
||||||
rig relays). */
|
/* VFO A/B style rigs swap VFO on split Tx so we need to disable
|
||||||
|
split for certainty */
|
||||||
freq_t orig_freq, second_freq;
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
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, &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;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find out what the split VFO, Freq, Mode and Width are.
|
|
||||||
|
|
||||||
Leaves the split VFO as current and returns a current VFO to switch
|
|
||||||
back to. The current VFO may be NONE in which case no switch back is
|
|
||||||
required */
|
|
||||||
static int get_split_status (RIG * rig, vfo_t * curr_vfo,
|
|
||||||
freq_t * split_freq,
|
|
||||||
rmode_t * split_mode,
|
|
||||||
pbwidth_t * split_width)
|
|
||||||
{
|
|
||||||
/* 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).
|
|
||||||
|
|
||||||
There is a further complication in that A/B VFO style Icoms swap
|
|
||||||
VFOs during split Tx but there is no guaranteed way of querying Tx
|
|
||||||
status. In this case we must briefly turn off split to read the Rx
|
|
||||||
VFO details. Even more complex if the VFOs are set the same then
|
|
||||||
only by adjusting one before disabling split can we be sure that we
|
|
||||||
have identified which is which.
|
|
||||||
|
|
||||||
This all relies on some assumptions:- the rig can only be set or
|
|
||||||
reset to and from split mode via this library, when split the Tx
|
|
||||||
status must remain constant through this sequence. */
|
|
||||||
|
|
||||||
int status;
|
|
||||||
struct icom_priv_data * priv = (struct icom_priv_data *)rig->state.priv;
|
|
||||||
vfo_t rx_vfo, tx_vfo;
|
|
||||||
freq_t orig_freq;
|
|
||||||
rmode_t orig_mode;
|
|
||||||
pbwidth_t orig_width;
|
|
||||||
unsigned char ackbuf[MAXFRAMELEN];
|
|
||||||
int ack_len = sizeof(ackbuf);
|
|
||||||
int tx_split = 0;
|
|
||||||
freq_t offset = 0;
|
|
||||||
|
|
||||||
*curr_vfo = RIG_VFO_NONE;
|
|
||||||
|
|
||||||
status = get_split_vfos(rig, &rx_vfo, &tx_vfo);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
|
|
||||||
// get current frequency, mode and 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;
|
|
||||||
|
|
||||||
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)) {
|
|
||||||
/* A/B VFO rigs swap VFO on split Tx so we need to find out if we are in Tx */
|
|
||||||
if (priv->split_on) { /* broken if user changes split on rig :( */
|
|
||||||
status = icom_transaction (rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
if (ack_len != 1 || ackbuf[0] != ACK) {
|
|
||||||
rig_debug(RIG_DEBUG_ERR,"icom_set_split_freq_mode: ack NG (%#.2x), "
|
|
||||||
"len=%d\n", ackbuf[0],ack_len);
|
|
||||||
return -RIG_ERJCTED;
|
|
||||||
}
|
|
||||||
status = icom_get_freq(rig, RIG_VFO_CURR, split_freq);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
if (*split_freq == orig_freq) {
|
|
||||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, split_mode, split_width);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
}
|
|
||||||
if (*split_freq != orig_freq || *split_mode != orig_mode || *split_width != orig_width) {
|
|
||||||
/* definitely split tx as turning off split changed VFO */
|
|
||||||
tx_split = -1;
|
|
||||||
/* restore split state */
|
|
||||||
status = icom_transaction (rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
if (ack_len != 1 || ackbuf[0] != ACK) {
|
if (ack_len != 1 || ackbuf[0] != ACK) {
|
||||||
rig_debug(RIG_DEBUG_ERR,"icom_set_split_freq_mode: ack NG (%#.2x), "
|
rig_debug(RIG_DEBUG_ERR,"icom_set_split_freq_mode: ack NG (%#.2x), "
|
||||||
"len=%d\n", ackbuf[0],ack_len);
|
"len=%d\n", ackbuf[0],ack_len);
|
||||||
return -RIG_ERJCTED;
|
return -RIG_ERJCTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
if (RIG_OK != (rc = get_split_vfos(rig, &rx_vfo, &tx_vfo))) return rc;
|
||||||
/* may still be split Tx so change Tx F +10Hz then split on and check F */
|
if (RIG_OK != (rc = icom_set_vfo(rig, tx_vfo))) return rc;
|
||||||
status = icom_set_vfo(rig, tx_vfo);
|
if (RIG_OK != (rc = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) return rc;
|
||||||
if (status != RIG_OK) return status;
|
if (RIG_OK != (rc = icom_set_vfo(rig, rx_vfo))) return rc;
|
||||||
offset = Hz(10);
|
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
|
||||||
status = icom_set_freq(rig, RIG_VFO_CURR, *split_freq + offset);
|
&& priv->split_on) {
|
||||||
if (status != RIG_OK) return status;
|
/* Re-enable split */
|
||||||
/* restore split state */
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
status = icom_transaction (rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
if (ack_len != 1 || ackbuf[0] != ACK) {
|
|
||||||
rig_debug(RIG_DEBUG_ERR,"icom_set_split_freq_mode: ack NG (%#.2x), "
|
|
||||||
"len=%d\n", ackbuf[0],ack_len);
|
|
||||||
return -RIG_ERJCTED;
|
|
||||||
}
|
}
|
||||||
freq_t temp_freq;
|
return rc;
|
||||||
status = icom_get_freq(rig, RIG_VFO_CURR, &temp_freq);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
if (temp_freq != *split_freq + offset) {
|
|
||||||
/* frequency changed so we must be in Tx */
|
|
||||||
tx_split = -1;
|
|
||||||
/* VFO B current since split Tx */
|
|
||||||
status = icom_set_vfo(rig, tx_vfo);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tx_split) {
|
|
||||||
if (0 == offset) {
|
|
||||||
status = icom_set_vfo(rig, tx_vfo);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
status = icom_get_freq(rig, RIG_VFO_CURR, split_freq);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
status = rig->caps->get_mode (rig, RIG_VFO_CURR, split_mode, split_width);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!tx_split && (*split_freq != orig_freq
|
|
||||||
|| *split_mode != orig_mode
|
|
||||||
|| *split_width != orig_width
|
|
||||||
|| priv->split_on)) {
|
|
||||||
/* Rx VFO must have been selected when we started so switch back
|
|
||||||
to it. We may be wrong but in that case A & B are the same so
|
|
||||||
it doesn't matter so long as in split Tx is always VFO B */
|
|
||||||
*curr_vfo = rx_vfo;
|
|
||||||
}
|
|
||||||
return RIG_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* icom_set_split_freq_mode
|
* icom_set_split_freq_mode
|
||||||
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
||||||
* icom_set_vfo,icom_set_mode works for this rig
|
* 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 icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mode, pbwidth_t tx_width)
|
||||||
{
|
{
|
||||||
int status;
|
int rc;
|
||||||
struct icom_priv_data * priv = (struct icom_priv_data *)rig->state.priv;
|
struct icom_priv_data * priv = (struct icom_priv_data *)rig->state.priv;
|
||||||
|
unsigned char ackbuf[MAXFRAMELEN];
|
||||||
|
int ack_len=sizeof(ackbuf);
|
||||||
|
vfo_t rx_vfo, tx_vfo;
|
||||||
|
|
||||||
/* This method works also in memory mode(RIG_VFO_MEM) */
|
/* This method works also in memory mode(RIG_VFO_MEM) */
|
||||||
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
||||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
if (status != RIG_OK) return status;
|
if (RIG_OK != (rc = rig_set_freq(rig, RIG_VFO_CURR, tx_freq))) return rc;
|
||||||
|
if (RIG_OK != (rc = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) return rc;
|
||||||
status = rig_set_freq(rig, RIG_VFO_CURR, tx_freq);
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
if (status != RIG_OK) return status;
|
return rc;
|
||||||
|
|
||||||
status = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
|
|
||||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
|
||||||
if (status != RIG_OK) return status;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vfo_t curr_vfo;
|
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||||
freq_t split_freq;
|
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||||
rmode_t split_mode;
|
assumptions allow us to deal with the lack of VFO and split
|
||||||
pbwidth_t split_width;
|
queries */
|
||||||
status = get_split_status (rig, &curr_vfo, &split_freq,
|
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
|
||||||
&split_mode, &split_width);
|
&& priv->split_on) { /* broken if user changes split on rig :( */
|
||||||
if (status != RIG_OK) return status;
|
/* VFO A/B style rigs swap VFO on split Tx so we need to disable
|
||||||
|
split for certainty */
|
||||||
status = rig_set_freq(rig, RIG_VFO_CURR, tx_freq);
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
if (status != RIG_OK) return status;
|
if (ack_len != 1 || ackbuf[0] != ACK) {
|
||||||
status = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width);
|
rig_debug(RIG_DEBUG_ERR,"icom_set_split_freq_mode: ack NG (%#.2x), "
|
||||||
if (status != RIG_OK) return status;
|
"len=%d\n", ackbuf[0],ack_len);
|
||||||
|
return -RIG_ERJCTED;
|
||||||
if (curr_vfo != RIG_VFO_NONE)
|
|
||||||
{
|
|
||||||
status = icom_set_vfo(rig, curr_vfo);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return status;
|
if (RIG_OK != (rc = get_split_vfos(rig, &rx_vfo, &tx_vfo))) return rc;
|
||||||
|
if (RIG_OK != (rc = icom_set_vfo(rig, tx_vfo))) return rc;
|
||||||
|
if (RIG_OK != (rc = rig_set_freq(rig, RIG_VFO_CURR, tx_freq))) return rc;
|
||||||
|
if (RIG_OK != (rc = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) 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)
|
||||||
|
&& priv->split_on) {
|
||||||
|
/* Re-enable split */
|
||||||
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2174,82 +1931,54 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mod
|
||||||
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
* Assumes rig!=NULL, rig->state.priv!=NULL,
|
||||||
* rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL
|
* rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL
|
||||||
* icom_set_vfo,icom_get_mode works for this rig
|
* 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 icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq, rmode_t *tx_mode, pbwidth_t *tx_width)
|
||||||
{
|
{
|
||||||
int status;
|
int rc;
|
||||||
vfo_t rx_vfo, tx_vfo;
|
vfo_t rx_vfo, tx_vfo;
|
||||||
struct icom_priv_data *priv;
|
struct icom_priv_data *priv;
|
||||||
struct rig_state *rs;
|
struct rig_state *rs;
|
||||||
|
unsigned char ackbuf[MAXFRAMELEN];
|
||||||
|
int ack_len=sizeof(ackbuf);
|
||||||
|
|
||||||
rs = &rig->state;
|
rs = &rig->state;
|
||||||
priv = (struct icom_priv_data*)rs->priv;
|
priv = (struct icom_priv_data*)rs->priv;
|
||||||
|
|
||||||
/* This method works also in memory mode(RIG_VFO_MEM) */
|
/* This method works also in memory mode(RIG_VFO_MEM) */
|
||||||
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) {
|
||||||
status = icom_vfo_op(rig, vfo, RIG_OP_XCHG);
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
if (status != RIG_OK)
|
if (RIG_OK != (rc = rig_get_freq(rig, RIG_VFO_CURR, tx_freq))) return rc;
|
||||||
return status;
|
if (RIG_OK != (rc = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) return rc;
|
||||||
|
if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) return rc;
|
||||||
status = rig_get_freq(rig, RIG_VFO_CURR, tx_freq);
|
return rc;
|
||||||
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
|
/* In the case of rigs with an A/B VFO arrangement we assume the
|
||||||
even though Icom provides no way to tell what the current VFO is. So
|
current VFO is VFO A and the split Tx VFO is always VFO B. These
|
||||||
we read current frequency and mode and compare with SUB/B, this
|
assumptions allow us to deal with the lack of VFO and split
|
||||||
gives up a clue so long as both VFOs are not the same frequency and
|
queries */
|
||||||
mode (and we don't really care if they are, the price for not using
|
if ((rig->state.vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)
|
||||||
VFO_XCHG, which will glitch the RX and TX and, possibly clatter the
|
&& priv->split_on) { /* broken if user changes split on rig :( */
|
||||||
rig relays). */
|
/* VFO A/B style rigs swap VFO on split Tx so we need to disable
|
||||||
|
split for certainty */
|
||||||
freq_t orig_freq;
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
rmode_t orig_mode;
|
if (ack_len != 1 || ackbuf[0] != ACK) {
|
||||||
pbwidth_t orig_width;
|
rig_debug(RIG_DEBUG_ERR,"icom_set_split_freq_mode: ack NG (%#.2x), "
|
||||||
|
"len=%d\n", ackbuf[0],ack_len);
|
||||||
status = icom_get_freq(rig, RIG_VFO_CURR, &orig_freq);
|
return -RIG_ERJCTED;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return status;
|
if (RIG_OK != (rc = get_split_vfos(rig, &rx_vfo, &tx_vfo))) return rc;
|
||||||
|
if (RIG_OK != (rc = icom_set_vfo(rig, tx_vfo))) return rc;
|
||||||
|
if (RIG_OK != (rc = icom_get_freq(rig, RIG_VFO_CURR, tx_freq))) return rc;
|
||||||
|
if (RIG_OK != (rc = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) 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)
|
||||||
|
&& priv->split_on) {
|
||||||
|
/* Re-enable split */
|
||||||
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len))) return rc;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2261,7 +1990,7 @@ int icom_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;
|
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), retval;
|
int ack_len=sizeof(ackbuf), rc;
|
||||||
int split_sc;
|
int split_sc;
|
||||||
|
|
||||||
switch (split) {
|
switch (split) {
|
||||||
|
@ -2270,17 +1999,20 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
|
||||||
break;
|
break;
|
||||||
case RIG_SPLIT_ON:
|
case RIG_SPLIT_ON:
|
||||||
split_sc = S_SPLT_ON;
|
split_sc = S_SPLT_ON;
|
||||||
|
if (!priv->split_on) {
|
||||||
|
/* 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_OK != (rc = icom_set_vfo(rig, RIG_VFO_A))) return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rig_debug(RIG_DEBUG_ERR,"%s: Unsupported split %d", __FUNCTION__, split);
|
rig_debug(RIG_DEBUG_ERR,"%s: Unsupported split %d", __FUNCTION__, split);
|
||||||
return -RIG_EINVAL;
|
return -RIG_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = icom_transaction (rig, C_CTL_SPLT, split_sc, NULL, 0,
|
if (RIG_OK != (rc = icom_transaction (rig, C_CTL_SPLT, split_sc, NULL, 0,
|
||||||
ackbuf, &ack_len);
|
ackbuf, &ack_len))) return rc;
|
||||||
if (retval != RIG_OK)
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
if (ack_len != 1 || ackbuf[0] != ACK) {
|
if (ack_len != 1 || ackbuf[0] != ACK) {
|
||||||
rig_debug(RIG_DEBUG_ERR,"icom_set_split: ack NG (%#.2x), "
|
rig_debug(RIG_DEBUG_ERR,"icom_set_split: ack NG (%#.2x), "
|
||||||
"len=%d\n", ackbuf[0],ack_len);
|
"len=%d\n", ackbuf[0],ack_len);
|
||||||
|
|
Ładowanie…
Reference in New Issue