diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h index 15c4bc78a..b94af30ce 100644 --- a/include/hamlib/rig.h +++ b/include/hamlib/rig.h @@ -1591,7 +1591,9 @@ struct rig_state { pbwidth_t current_width; /*!< Passband width currently set */ vfo_t tx_vfo; /*!< Tx VFO currently set */ int mode_list; /*!< Complete list of modes for this rig */ - + int transmit; /*!< rig should be transmitting i.e. hard + wired PTT asserted - used by rigs that + don't do CAT while in Tx */ }; diff --git a/src/rig.c b/src/rig.c index aa7aff02e..701e3a412 100644 --- a/src/rig.c +++ b/src/rig.c @@ -1472,7 +1472,8 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const struct rig_caps *caps; struct rig_state *rs = &rig->state; - int retcode, rc2; + int retcode = RIG_OK; + int rc2; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -1498,44 +1499,37 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) if ((caps->targetable_vfo & RIG_TARGETABLE_PURE) || vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) { - return caps->set_ptt(rig, vfo, ptt); + + retcode = caps->set_ptt(rig, vfo, ptt); + } else { + if (!caps->set_vfo) { + return -RIG_ENTARGET; + } + + curr_vfo = rig->state.current_vfo; + retcode = caps->set_vfo(rig, vfo); + + if (retcode == RIG_OK) { + retcode = caps->set_ptt(rig, vfo, ptt); + /* try and revert even if we had an error above */ + rc2 = caps->set_vfo(rig, curr_vfo); + + /* return the first error code */ + if (RIG_OK == retcode) { + retcode = rc2; + } + } } - - if (!caps->set_vfo) { - return -RIG_ENTARGET; - } - - curr_vfo = rig->state.current_vfo; - retcode = caps->set_vfo(rig, vfo); - - if (retcode != RIG_OK) { - return retcode; - } - - retcode = caps->set_ptt(rig, vfo, ptt); - /* try and revert even if we had an error above */ - rc2 = caps->set_vfo(rig, curr_vfo); - - /* return the first error code */ - if (RIG_OK == retcode) { - retcode = rc2; - } - - return retcode; - break; case RIG_PTT_SERIAL_DTR: - /* when the PTT port is not the control port we want to free the port when PTT is reset and seize the port when PTT is set, this allows limited sharing of the PTT port between applications so long as there is no contention */ if (strcmp(rs->pttport.pathname, rs->rigport.pathname) - && rs->pttport.fd < 0) { - if (RIG_PTT_OFF == ptt) { - return RIG_OK; /* nothing to do here */ - } + && rs->pttport.fd < 0 + && RIG_PTT_OFF != ptt) { rs->pttport.fd = ser_open(&rs->pttport); @@ -1548,7 +1542,7 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) } /* Needed on Linux because the serial port driver sets RTS/DTR - high on open - set both low since we offer no control of + high on open - set both since we offer no control of the non-PTT line and low is better than high */ retcode = ser_set_rts(&rs->pttport, 0); @@ -1561,72 +1555,73 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) if (strcmp(rs->pttport.pathname, rs->rigport.pathname) && ptt == RIG_PTT_OFF) { - /* free the port */ - ser_close(&rs->pttport); + + /* free the port */ + ser_close(&rs->pttport); } - return retcode; + break; case RIG_PTT_SERIAL_RTS: - /* when the PTT port is not the control port we want to free the port when PTT is reset and seize the port when PTT is set, this allows limited sharing of the PTT port between applications so long as there is no contention */ if (strcmp(rs->pttport.pathname, rs->rigport.pathname) - && rs->pttport.fd < 0) { - if (RIG_PTT_OFF == ptt) { - return RIG_OK; /* nothing to do here */ - } + && rs->pttport.fd < 0 + && RIG_PTT_OFF != ptt) { - rs->pttport.fd = ser_open(&rs->pttport); + rs->pttport.fd = ser_open(&rs->pttport); - if (rs->pttport.fd < 0) { - rig_debug(RIG_DEBUG_ERR, - "%s: cannot open PTT device \"%s\"\n", - __func__, - rs->pttport.pathname); - return -RIG_EIO; - } + if (rs->pttport.fd < 0) { + rig_debug(RIG_DEBUG_ERR, + "%s: cannot open PTT device \"%s\"\n", + __func__, + rs->pttport.pathname); + return -RIG_EIO; + } - /* Needed on Linux because the serial port driver sets RTS/DTR - high on open - set both low since we offer no control of - the non-PTT line and low is better than high */ - retcode = ser_set_dtr(&rs->pttport, 0); + /* Needed on Linux because the serial port driver sets RTS/DTR + high on open - set both since we offer no control of the + non-PTT line and low is better than high */ + retcode = ser_set_dtr(&rs->pttport, 0); - if (RIG_OK != retcode) { - return retcode; - } + if (RIG_OK != retcode) { + return retcode; + } } - retcode = ser_set_rts(&rig->state.pttport, ptt != RIG_PTT_OFF); if (strcmp(rs->pttport.pathname, rs->rigport.pathname) && ptt == RIG_PTT_OFF) { - /* free the port */ - ser_close(&rs->pttport); - } - return retcode; + /* free the port */ + ser_close(&rs->pttport); + } + break; case RIG_PTT_PARALLEL: - return par_ptt_set(&rig->state.pttport, ptt); + retcode = par_ptt_set(&rig->state.pttport, ptt); + break; case RIG_PTT_CM108: - return cm108_ptt_set(&rig->state.pttport, ptt); + retcode = cm108_ptt_set(&rig->state.pttport, ptt); + break; case RIG_PTT_GPIO: case RIG_PTT_GPION: - return gpio_ptt_set(&rig->state.pttport, ptt); - - case RIG_PTT_NONE: - return -RIG_ENAVAIL; /* not available */ + retcode = gpio_ptt_set(&rig->state.pttport, ptt); + break; default: return -RIG_EINVAL; } - return RIG_OK; + if (RIG_OK == retcode) { + rs->transmit = ptt != RIG_PTT_OFF; + } + + return retcode; } @@ -1663,14 +1658,16 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) switch (rig->state.pttport.type.ptt) { case RIG_PTT_RIG: case RIG_PTT_RIG_MICDATA: - if (caps->get_ptt == NULL) { - return -RIG_ENIMPL; + if (!caps->get_ptt) { + *ptt = rs->transmit ? RIG_PTT_ON : RIG_PTT_OFF; + return RIG_OK; } if ((caps->targetable_vfo & RIG_TARGETABLE_PURE) || vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) { - return caps->get_ptt(rig, vfo, ptt); + + return caps->get_ptt(rig, vfo, ptt); } if (!caps->set_vfo) { @@ -1689,14 +1686,12 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { - /* return the first error code */ - retcode = rc2; + /* return the first error code */ + retcode = rc2; } return retcode; - break; - case RIG_PTT_SERIAL_RTS: if (caps->get_ptt) { return caps->get_ptt(rig, vfo, ptt); @@ -1704,8 +1699,9 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) if (strcmp(rs->pttport.pathname, rs->rigport.pathname) && rs->pttport.fd < 0) { - /* port is closed so assume PTT off */ - *ptt = RIG_PTT_OFF; + + /* port is closed so assume PTT off */ + *ptt = RIG_PTT_OFF; } else { retcode = ser_get_rts(&rig->state.pttport, &status); *ptt = status ? RIG_PTT_ON : RIG_PTT_OFF; @@ -1720,8 +1716,9 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) if (strcmp(rs->pttport.pathname, rs->rigport.pathname) && rs->pttport.fd < 0) { - /* port is closed so assume PTT off */ - *ptt = RIG_PTT_OFF; + + /* port is closed so assume PTT off */ + *ptt = RIG_PTT_OFF; } else { retcode = ser_get_dtr(&rig->state.pttport, &status); *ptt = status ? RIG_PTT_ON : RIG_PTT_OFF; diff --git a/yaesu/ft747.c b/yaesu/ft747.c index c739fcf68..81dd0c00b 100644 --- a/yaesu/ft747.c +++ b/yaesu/ft747.c @@ -284,7 +284,6 @@ const struct rig_caps ft747_caps = { .set_split_vfo = ft747_set_split, /* set split */ .get_split_vfo = ft747_get_split, /* get split */ .set_ptt = ft747_set_ptt, /* set ptt */ - .get_ptt = ft747_get_ptt, /* get ptt */ .set_mem = ft747_set_mem, /* set mem */ .get_mem = ft747_get_mem, /* get mem */ }; @@ -695,38 +694,6 @@ int ft747_set_ptt(RIG *rig,vfo_t vfo, ptt_t ptt) { return ft747_send_priv_cmd(rig,cmd_index); } -int ft747_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { - struct ft747_priv_data *p; - unsigned char status; /* ft747 mode */ - int ret; - - p = (struct ft747_priv_data*)rig->state.priv; - - ret = ft747_get_update_data(rig); /* get whole shebang from rig */ - if (ret < 0) - return ret; - - status = p->update_data[FT747_SUMO_DISPLAYED_STATUS]; - status = status & SF_RXTX; /* check RXTX bit*/ - - rig_debug(RIG_DEBUG_VERBOSE,"ft747: ptt status = %x \n", status); - - /* - * translate mode from ft747 to generic. - */ - - if (status) { - rig_debug(RIG_DEBUG_VERBOSE,"ft747: PTT = ON \n"); - (*ptt) = RIG_PTT_ON; - return RIG_OK; - } else { - rig_debug(RIG_DEBUG_VERBOSE,"ft747: PTT = OFF \n"); - (*ptt) = RIG_PTT_OFF; - return RIG_OK; - } - -} - int ft747_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ft747_priv_data *p; @@ -788,28 +755,30 @@ static int ft747_get_update_data(RIG *rig) { if (!rig_check_cache_timeout(&p->status_tv, FT747_CACHE_TIMEOUT)) return RIG_OK; - serial_flush(rigport); + if (!rig->state.transmit) { /* rig doesn't respond in Tx mode */ + serial_flush(rigport); - /* send UPDATE comand to fetch data*/ + /* send UPDATE comand to fetch data*/ - ret = ft747_send_priv_cmd(rig,FT_747_NATIVE_UPDATE); - if (ret < 0) - return ret; + ret = ft747_send_priv_cmd(rig,FT_747_NATIVE_UPDATE); + if (ret < 0) + return ret; - ret = read_block(rigport, (char *) p->update_data, - FT747_STATUS_UPDATE_DATA_LENGTH); - if (ret < 0) - return ret; + ret = read_block(rigport, (char *) p->update_data, + FT747_STATUS_UPDATE_DATA_LENGTH); + if (ret < 0) + return ret; + + port_timeout = rigport->timeout; + rigport->timeout = 100; /* ms */ + /* read sometimes-missing last byte (345th), but don't fail */ + read_block(rigport, &last_byte, 1); + rigport->timeout = port_timeout; + } /* update cache date */ gettimeofday(&p->status_tv, NULL); - port_timeout = rigport->timeout; - rigport->timeout = 100; /* ms */ - /* read sometimes-missing last byte (345th), but don't fail */ - read_block(rigport, &last_byte, 1); - rigport->timeout = port_timeout; - return RIG_OK; } diff --git a/yaesu/ft747.h b/yaesu/ft747.h index fcc5414c0..1514b21f5 100644 --- a/yaesu/ft747.h +++ b/yaesu/ft747.h @@ -190,7 +190,6 @@ static int ft747_set_vfo(RIG *rig, vfo_t vfo); /* select vfo */ static int ft747_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft747_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); -static int ft747_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft747_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft747_get_split(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); diff --git a/yaesu/ft847.c b/yaesu/ft847.c index d0fd2c775..f60b57fd9 100644 --- a/yaesu/ft847.c +++ b/yaesu/ft847.c @@ -845,13 +845,20 @@ int ft847_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft847_priv_data *p = (struct ft847_priv_data *) rig->state.priv; int n; - n = ft847_get_status(rig, FT_847_NATIVE_CAT_GET_TX_STATUS); if (n < 0) return n; *ptt = (p->tx_status & 0x80) ? RIG_PTT_OFF : RIG_PTT_ON; + /* The CAT query above lies when PTT is asserted via the PTT pin on + the rear PACKET socket, it always returns Rx status. Given that + CAT PTT does not take audio from DATA IN on the rear PACKET + socket DTR or RTS PTT on the rear PACKET PTT pin is likely. So we + override if we know PTT was asserted via rig_set_ptt for any type + of PTT */ + if (RIG_PTT_OFF == *ptt && rig->state.transmit) *ptt = RIG_PTT_ON; + return RIG_OK; }