diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h index 6a0647518..dc62832e7 100644 --- a/include/hamlib/rig.h +++ b/include/hamlib/rig.h @@ -2380,6 +2380,7 @@ typedef struct hamlib_port { int fd_sync_error_read; /*!< file descriptor for reading synchronous data error codes */ #endif short timeout_retry; /*!< number of retries to make in case of read timeout errors, some serial interfaces may require this, 0 to disable */ + int post_ptt_delay; /*!< delay after PTT to allow for relays and such */ } hamlib_port_t; @@ -2758,11 +2759,11 @@ struct rig_state { volatile int morse_data_handler_thread_run; void *morse_data_handler_priv_data; FIFO_RIG *fifo_morse; + int doppler; /*!< True if doppler changing detected */ char *multicast_data_addr; /*!< Multicast data UDP address for publishing rig data and state */ int multicast_data_port; /*!< Multicast data UDP port for publishing rig data and state */ char *multicast_cmd_addr; /*!< Multicast command server UDP address for sending commands to rig */ int multicast_cmd_port; /*!< Multicast command server UDP port for sending commands to rig */ - volatile int multicast_receiver_run; void *multicast_receiver_priv_data; }; diff --git a/rigs/kenwood/kenwood.c b/rigs/kenwood/kenwood.c index c5fd97688..4e87543ba 100644 --- a/rigs/kenwood/kenwood.c +++ b/rigs/kenwood/kenwood.c @@ -1862,15 +1862,17 @@ int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq) } // Malchite is so slow we don't do the get_freq - if (!RIG_IS_MALACHITE) + // And when we have detected Doppler operations we just set the freq all the time + // This should provide stable timing for set_ptt operation so relay delays are consistent + if (!RIG_IS_MALACHITE && rig->state.doppler == 0) { - rig_get_freq(rig, tvfo, &tfreq); + rig_get_freq(rig, tvfo, &tfreq); - if (tfreq == freq) - { - rig_debug(RIG_DEBUG_TRACE, "%s: no freq change needed\n", __func__); - RETURNFUNC2(RIG_OK); - } + if (tfreq == freq) + { + rig_debug(RIG_DEBUG_TRACE, "%s: no freq change needed\n", __func__); + RETURNFUNC2(RIG_OK); + } } switch (tvfo) diff --git a/rigs/kenwood/kenwood.h b/rigs/kenwood/kenwood.h index be0a28dd8..c455685ff 100644 --- a/rigs/kenwood/kenwood.h +++ b/rigs/kenwood/kenwood.h @@ -28,7 +28,7 @@ #include "token.h" #include "idx_builtin.h" -#define BACKEND_VER "20231025" +#define BACKEND_VER "20231031" #define EOM_KEN ';' #define EOM_TH '\r' diff --git a/rigs/yaesu/newcat.c b/rigs/yaesu/newcat.c index 8f69532c7..556e065d2 100644 --- a/rigs/yaesu/newcat.c +++ b/rigs/yaesu/newcat.c @@ -211,6 +211,8 @@ const cal_table_float_t yaesu_default_id_meter_cal = static ncboolean is_ft450; static ncboolean is_ft710; static ncboolean is_ft891; +static ncboolean is_ft897; +static ncboolean is_ft897d; static ncboolean is_ft950; static ncboolean is_ft991; static ncboolean is_ft2000; @@ -497,6 +499,8 @@ int newcat_init(RIG *rig) is_ft450 = newcat_is_rig(rig, RIG_MODEL_FT450); is_ft450 |= newcat_is_rig(rig, RIG_MODEL_FT450D); is_ft891 = newcat_is_rig(rig, RIG_MODEL_FT891); + is_ft897 = newcat_is_rig(rig, RIG_MODEL_FT897); + is_ft897d = newcat_is_rig(rig, RIG_MODEL_FT897D); is_ft950 = newcat_is_rig(rig, RIG_MODEL_FT950); is_ft991 = newcat_is_rig(rig, RIG_MODEL_FT991); is_ft2000 = newcat_is_rig(rig, RIG_MODEL_FT2000); @@ -847,7 +851,7 @@ int newcat_60m_exception(RIG *rig, freq_t freq, mode_t mode) } // some rigs need to skip freq/mode settings as 60M only operates in memory mode - if (is_ft991) { return 1; } + if (is_ft991 || is_ft897 || is_ft897d || is_ftdx5000) { return 1; } if (!is_ftdx10 && !is_ft710 && !is_ftdx101d && !is_ftdx101mp) { return 0; } @@ -5459,7 +5463,7 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) } break; default: - rig_debug(RIG_DEBUG_ERR, "%s: unknown level=%08lx\n", __func__, level); + rig_debug(RIG_DEBUG_ERR, "%s: unknown level=%08llx\n", __func__, (long long unsigned int)level); RETURNFUNC(-RIG_EINVAL); } diff --git a/rigs/yaesu/newcat.h b/rigs/yaesu/newcat.h index d7c451587..29a639eb7 100644 --- a/rigs/yaesu/newcat.h +++ b/rigs/yaesu/newcat.h @@ -50,7 +50,7 @@ typedef char ncboolean; /* shared function version */ -#define NEWCAT_VER "20231024" +#define NEWCAT_VER "20231101" /* Hopefully large enough for future use, 128 chars plus '\0' */ #define NEWCAT_DATA_LEN 129 diff --git a/simulators/simts450.c b/simulators/simts450.c index e29bea21d..08ab439bb 100644 --- a/simulators/simts450.c +++ b/simulators/simts450.c @@ -27,6 +27,7 @@ int filternum = 7; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; int tomode = 0; +int keyspd = 25; int getmyline(int fd, char *buf) @@ -203,17 +204,6 @@ int main(int argc, char *argv[]) WRITE(fd, buf, strlen(buf)); } - else if (strncmp(buf, "AI", 2) == 0) - { - if (strcmp(buf, "AI;")) - { - printf("%s\n", buf); - hl_usleep(mysleep * 1000); - pbuf = "AI0;"; - WRITE(fd, pbuf, strlen(pbuf)); - } - } - else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); @@ -251,10 +241,9 @@ int main(int argc, char *argv[]) { sscanf(buf, "FB%d", &freqb); } - else if (strncmp(buf, "AI;", 3) == 0) + else if (strncmp(buf, "AI", 2) == 0) { - SNPRINTF(buf, sizeof(buf), "AI0;"); - WRITE(fd, buf, strlen(buf)); + // nothing to do yet } else if (strncmp(buf, "PS;", 3) == 0) @@ -314,7 +303,7 @@ int main(int argc, char *argv[]) } else if (strcmp(buf, "FT;") == 0) { - SNPRINTF(buf, sizeof(buf), "FR%d;", vfo_tx); + SNPRINTF(buf, sizeof(buf), "FT%d;", vfo_tx); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FT", 2) == 0) @@ -358,12 +347,11 @@ int main(int argc, char *argv[]) } } + else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } - - } return 0; diff --git a/src/conf.c b/src/conf.c index 3c17ecb11..24ea22d78 100644 --- a/src/conf.c +++ b/src/conf.c @@ -61,6 +61,11 @@ static const struct confparams frontend_cfg_params[] = "Delay in ms between each command sent out", "0", RIG_CONF_NUMERIC, { .n = { 0, 1000, 1 } } }, + { + TOK_POST_PTT_DELAY, "post_ptt_delay", "Post ptt delay", + "Delay in ms after PTT is asserted", + "0", RIG_CONF_NUMERIC, { .n = { 0, 2000, 1 } } // 2000ms should be more than enough + }, { TOK_TIMEOUT, "timeout", "Timeout", "Timeout in ms", "0", RIG_CONF_NUMERIC, { .n = { 0, 10000, 1 } } @@ -71,7 +76,7 @@ static const struct confparams frontend_cfg_params[] = }, { TOK_TIMEOUT_RETRY, "timeout_retry", "Number of retries for read timeouts", - "Set the number of retries for data read timeouts that may occur especially with some serial interfaces", + "Set the # of retries for read timeouts that may occur with some serial interfaces", "1", RIG_CONF_NUMERIC, { .n = { 0, 100, 1 } } }, { @@ -91,8 +96,8 @@ static const struct confparams frontend_cfg_params[] = "0", RIG_CONF_NUMERIC, { .n = { 0.0, 1000.0, .001 } } }, { - TOK_POLL_INTERVAL, "poll_interval", "Rig state poll interval in milliseconds", - "Polling interval in milliseconds for transceive emulation, defaults to 1000, value of 0 disables polling", + TOK_POLL_INTERVAL, "poll_interval", "Rig state poll interval in ms", + "Polling interval in ms for transceive emulation, defaults to 1000, value of 0 disables polling", "1000", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } } }, { @@ -102,7 +107,7 @@ static const struct confparams frontend_cfg_params[] = }, { TOK_PTT_PATHNAME, "ptt_pathname", "PTT path name", - "Path name to the device file of the Push-To-Talk", + "Path to the device of the Push-To-Talk", "/dev/rig", RIG_CONF_STRING, }, { @@ -117,7 +122,7 @@ static const struct confparams frontend_cfg_params[] = }, { TOK_DCD_PATHNAME, "dcd_pathname", "DCD path name", - "Path name to the device file of the Data Carrier Detect (or squelch)", + "Path to the device of the Data Carrier Detect (or squelch)", "/dev/rig", RIG_CONF_STRING, }, { @@ -172,12 +177,12 @@ static const struct confparams frontend_cfg_params[] = }, { TOK_ASYNC, "async", "Asynchronous data transfer support", - "True enables asynchronous data transfer for backends that support it. This allows use of transceive and spectrum data.", + "True enables async data for rigs that support it to allow use of transceive and spectrum data", "0", RIG_CONF_CHECKBUTTON, { } }, { TOK_TUNER_CONTROL_PATHNAME, "tuner_control_pathname", "Tuner script/program path name", - "Path name to a script/program to control a tuner with 1 argument of 0/1 for Tuner Off/On", + "Path to a program to control a tuner with 1 argument of 0/1 for Tuner Off/On", "hamlib_tuner_control", RIG_CONF_STRING, }, { @@ -818,6 +823,10 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) SNPRINTF(val, val_len, "%d", rs->rigport.post_write_delay); break; + case TOK_POST_PTT_DELAY: + SNPRINTF(val, val_len, "%d", rs->rigport.post_ptt_delay); + break; + case TOK_TIMEOUT: SNPRINTF(val, val_len, "%d", rs->rigport.timeout); break; diff --git a/src/rig.c b/src/rig.c index 1165c8c70..57d6a951d 100644 --- a/src/rig.c +++ b/src/rig.c @@ -1905,6 +1905,28 @@ int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) rig_strvfo(vfo), freq); #endif + if (rig->state.doppler == 0) + { + if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN || (vfo == RIG_VFO_CURR && rig->state.current_vfo == RIG_VFO_A)) + { + if (rig->state.cache.freqMainA != freq && (((int)freq % 10) != 0)) + { + rig->state.doppler = 1; + rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): potential doppler detected because old freq %f != new && new freq has 1Hz or such values\n", __func__, __LINE__, rig->state.cache.freqMainA); + } + freq += rig->state.offset_vfoa; + } + else if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB || (vfo == RIG_VFO_CURR && rig->state.current_vfo == RIG_VFO_B)) + { + if (rig->state.cache.freqMainB != freq && ((int)freq % 10) != 0) + { + rig->state.doppler = 1; + rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): potential doppler detected because old freq %f != new && new freq has 1Hz or such values\n", __func__, __LINE__, rig->state.cache.freqMainB); + } + freq += rig->state.offset_vfob; + } + } + if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { freq += rig->state.offset_vfoa; } else if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { freq += rig->state.offset_vfob; } @@ -2313,9 +2335,11 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) __LINE__, rig->state.vfo_opt, rig->caps->rig_model); // If we're in vfo_mode then rigctld will do any VFO swapping we need + // If we detected doppler we skip the frequency check to make timing more consistent for relay control if ((caps->targetable_vfo & RIG_TARGETABLE_FREQ) || vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo - || (rig->state.vfo_opt == 1 && rig->caps->rig_model == RIG_MODEL_NETRIGCTL)) + || (rig->state.vfo_opt == 1 && rig->caps->rig_model == RIG_MODEL_NETRIGCTL + && rig->state.doppler == 0)) { // If rig does not have set_vfo we need to change vfo if (vfo == RIG_VFO_CURR && caps->set_vfo == NULL) @@ -3517,6 +3541,7 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) memcpy(&rig->state.pttport_deprecated, &rig->state.pttport, sizeof(rig->state.pttport_deprecated)); + if (rig->state.rigport.post_ptt_delay > 0) hl_usleep(rig->state.rigport.post_ptt_delay*1000); ELAPSED2; RETURNFUNC(retcode); diff --git a/src/token.h b/src/token.h index 53d568798..58b1f6aaa 100644 --- a/src/token.h +++ b/src/token.h @@ -97,6 +97,7 @@ #define TOK_TUNER_CONTROL_PATHNAME TOKEN_FRONTEND(38) /** \brief Number of retries permitted in case of read timeouts */ #define TOK_TIMEOUT_RETRY TOKEN_FRONTEND(39) +#define TOK_POST_PTT_DELAY TOKEN_FRONTEND(40) /* * rig specific tokens diff --git a/tests/dumpcaps.h b/tests/dumpcaps.h new file mode 100644 index 000000000..6b1562d4c --- /dev/null +++ b/tests/dumpcaps.h @@ -0,0 +1,3 @@ +#include + +int dumpconf_list(RIG *rig, FILE *fout); diff --git a/tests/dumpcaps_rot.h b/tests/dumpcaps_rot.h new file mode 100644 index 000000000..4e00e4181 --- /dev/null +++ b/tests/dumpcaps_rot.h @@ -0,0 +1,3 @@ +#include + +int dumpconf_list(ROT *rot, FILE *fout);