diff --git a/rigs/yaesu/ftx1.c b/rigs/yaesu/ftx1.c index db87a3989..f65e27a9b 100644 --- a/rigs/yaesu/ftx1.c +++ b/rigs/yaesu/ftx1.c @@ -35,6 +35,8 @@ #include "yaesu.h" #include "ftx1.h" +static const char cat_term = ';'; /* Yaesu command terminator */ + /* Prototypes */ static int ftx1_init(RIG *rig); static int ftx1_set_vfo(RIG *rig, vfo_t vfo); @@ -55,6 +57,11 @@ static int ftx1_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); static int ftx1_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code); static int ftx1_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); +/* Configuration parameters */ +const struct confparams ftx1_cfg_params[] = { + { RIG_CONF_END, NULL, } +}; + const struct confparams ftx1_ext_levels[] = { { @@ -154,6 +161,7 @@ const struct confparams ftx1_ext_levels[] = RIG_CONF_NUMERIC, { .n = { .min = 5, .max = 50, .step = 1 } }, }, + { RIG_CONF_END, NULL, } }; @@ -278,70 +286,71 @@ struct rig_caps ftx1_caps = /* mode/filter list, .remember = order matters! */ .filters = { - {FTX1_RTTY_DATA_RX_MODES, Hz(500)}, /* Normal RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(300)}, /* Narrow RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(3000)}, /* Wide RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(2400)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(2000)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(1700)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(1400)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(1200)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(800)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(450)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(400)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(350)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(250)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(200)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(150)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(100)}, /* RTTY, DATA */ - {FTX1_RTTY_DATA_RX_MODES, Hz(50)}, /* RTTY, DATA */ - {FTX1_CW_RX_MODES, Hz(2400)}, /* Normal CW */ - {FTX1_CW_RX_MODES, Hz(500)}, /* Narrow CW */ - {FTX1_CW_RX_MODES, Hz(3000)}, /* Wide CW */ - {FTX1_CW_RX_MODES, Hz(2000)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(1700)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(1400)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(1200)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(800)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(450)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(400)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(350)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(300)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(250)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(200)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(150)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(100)}, /* CW */ - {FTX1_CW_RX_MODES, Hz(50)}, /* CW */ - {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ - {RIG_MODE_SSB, Hz(1500)}, /* Narrow SSB */ - {RIG_MODE_SSB, Hz(3200)}, /* Wide SSB */ - {RIG_MODE_SSB, Hz(3000)}, /* SSB */ - {RIG_MODE_SSB, Hz(2900)}, /* SSB */ - {RIG_MODE_SSB, Hz(2800)}, /* SSB */ - {RIG_MODE_SSB, Hz(2700)}, /* SSB */ - {RIG_MODE_SSB, Hz(2600)}, /* SSB */ - {RIG_MODE_SSB, Hz(2500)}, /* SSB */ - {RIG_MODE_SSB, Hz(2300)}, /* SSB */ - {RIG_MODE_SSB, Hz(2200)}, /* SSB */ - {RIG_MODE_SSB, Hz(2100)}, /* SSB */ - {RIG_MODE_SSB, Hz(1950)}, /* SSB */ - {RIG_MODE_SSB, Hz(1650)}, /* SSB */ - {RIG_MODE_SSB, Hz(1350)}, /* SSB */ - {RIG_MODE_SSB, Hz(1100)}, /* SSB */ - {RIG_MODE_SSB, Hz(850)}, /* SSB */ - {RIG_MODE_SSB, Hz(600)}, /* SSB */ - {RIG_MODE_SSB, Hz(400)}, /* SSB */ - {RIG_MODE_SSB, Hz(200)}, /* SSB */ - {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ - {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ - {FTX1_FM_WIDE_RX_MODES, Hz(16000)}, /* Normal FM, PKTFM, C4FM */ - {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ + {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ + {RIG_MODE_SSB, Hz(1500)}, /* Narrow SSB */ + {RIG_MODE_SSB, Hz(3200)}, /* Wide SSB */ + {RIG_MODE_CW, Hz(500)}, /* Normal CW */ + {RIG_MODE_CW, Hz(300)}, /* Narrow CW */ + {RIG_MODE_CW, Hz(2400)}, /* Wide CW */ + {RIG_MODE_FM, Hz(16000)}, /* Normal FM */ + {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ + {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ + {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ + {FTX1_RTTY_DATA_RX_MODES, Hz(500)}, /* Normal RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(300)}, /* Narrow RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(3000)}, /* Wide RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(2400)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(2000)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(1700)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(1400)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(1200)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(800)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(450)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(400)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(350)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(250)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(200)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(150)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(100)}, /* RTTY, DATA */ + {FTX1_RTTY_DATA_RX_MODES, Hz(50)}, /* RTTY, DATA */ + {FTX1_CW_RX_MODES, Hz(2000)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(1700)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(1400)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(1200)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(800)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(450)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(400)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(350)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(300)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(250)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(200)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(150)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(100)}, /* CW */ + {FTX1_CW_RX_MODES, Hz(50)}, /* CW */ + {RIG_MODE_SSB, Hz(3000)}, /* SSB */ + {RIG_MODE_SSB, Hz(2900)}, /* SSB */ + {RIG_MODE_SSB, Hz(2800)}, /* SSB */ + {RIG_MODE_SSB, Hz(2700)}, /* SSB */ + {RIG_MODE_SSB, Hz(2600)}, /* SSB */ + {RIG_MODE_SSB, Hz(2500)}, /* SSB */ + {RIG_MODE_SSB, Hz(2300)}, /* SSB */ + {RIG_MODE_SSB, Hz(2200)}, /* SSB */ + {RIG_MODE_SSB, Hz(2100)}, /* SSB */ + {RIG_MODE_SSB, Hz(1950)}, /* SSB */ + {RIG_MODE_SSB, Hz(1650)}, /* SSB */ + {RIG_MODE_SSB, Hz(1350)}, /* SSB */ + {RIG_MODE_SSB, Hz(1100)}, /* SSB */ + {RIG_MODE_SSB, Hz(850)}, /* SSB */ + {RIG_MODE_SSB, Hz(600)}, /* SSB */ + {RIG_MODE_SSB, Hz(400)}, /* SSB */ + {RIG_MODE_SSB, Hz(200)}, /* SSB */ RIG_FLT_END, }, .ext_tokens = ftx1_ext_tokens, .extlevels = ftx1_ext_levels, + .cfgparams = ftx1_cfg_params, .priv = NULL, /* private data FIXME: */ @@ -350,7 +359,7 @@ struct rig_caps ftx1_caps = .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ - .set_freq = newcat_set_freq, + .set_freq = ftx1_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, @@ -364,16 +373,16 @@ struct rig_caps ftx1_caps = .get_split_freq = ftx1_get_split_freq, .get_split_mode = ftx1_get_split_mode, .set_split_mode = ftx1_set_split_mode, - .set_rit = newcat_set_rit, - .get_rit = newcat_get_rit, - .set_xit = newcat_set_xit, - .get_xit = newcat_get_xit, + .set_rit = ftx1_set_rit, + .get_rit = ftx1_get_rit, + .set_xit = ftx1_set_xit, + .get_xit = ftx1_get_xit, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_parm = newcat_get_parm, .set_parm = newcat_set_parm, - .get_level = newcat_get_level, - .set_level = newcat_set_level, + .get_level = ftx1_get_power_control, + .set_level = ftx1_set_power_control, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, @@ -394,8 +403,8 @@ struct rig_caps ftx1_caps = .get_dcs_sql = ftx1_get_dcs_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, - .set_ts = newcat_set_ts, - .get_ts = newcat_get_ts, + .set_ts = ftx1_set_ts, + .get_ts = ftx1_get_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, @@ -1207,4 +1216,351 @@ static int ftx1_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = STATE(rig)->current_vfo; RETURNFUNC2(RIG_OK); +} + +/* Error handling function */ +static int ftx1_handle_cat_error(RIG *rig, const char *response) +{ + if (strstr(response, "?;")) { + return -RIG_EPROTO; // Protocol error + } + if (strstr(response, "N;")) { + return -RIG_ERJCTED; // Command rejected + } + return RIG_OK; +} + + + +/* RIT/XIT functions */ +static int ftx1_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) +{ + struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; + int err; + ftx1info *rdata; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !rit) + { + return -RIG_EINVAL; + } + + rdata = (ftx1info *)priv->ret_data; + + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IF;"); + + if (RIG_OK != (err = newcat_get_cmd(rig))) + { + return err; + } + + debug_ftx1info_data(rdata); + + if (rdata->rx_clarifier == '1') + { + *rit = atoi(rdata->clarifier); + if (rdata->clarifier[0] == '-') + { + *rit = -*rit; + } + } + else + { + *rit = 0; + } + + return RIG_OK; +} + +static int ftx1_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) +{ + struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; + int err; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (rit == 0) + { + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC0;"); + } + else if (rit > 0) + { + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC+%04ld;", rit); + } + else + { + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%05ld;", rit); + } + + if (RIG_OK != (err = newcat_set_cmd(rig))) + { + return err; + } + + return RIG_OK; +} + +static int ftx1_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) +{ + struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; + int err; + ftx1info *rdata; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !xit) + { + return -RIG_EINVAL; + } + + rdata = (ftx1info *)priv->ret_data; + + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IF;"); + + if (RIG_OK != (err = newcat_get_cmd(rig))) + { + return err; + } + + debug_ftx1info_data(rdata); + + if (rdata->tx_clarifier == '1') + { + *xit = atoi(rdata->clarifier); + if (rdata->clarifier[0] == '-') + { + *xit = -*xit; + } + } + else + { + *xit = 0; + } + + return RIG_OK; +} + +static int ftx1_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) +{ + struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; + int err; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (xit == 0) + { + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "TC0;"); + } + else if (xit > 0) + { + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "TC+%04ld;", xit); + } + else + { + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "TC%05ld;", xit); + } + + if (RIG_OK != (err = newcat_set_cmd(rig))) + { + return err; + } + + return RIG_OK; +} + +/* Split functions */ +static int ftx1_get_split(RIG *rig, vfo_t vfo, split_t *split) +{ + int err; + split_t is_split; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (!rig || !split) + { + return -RIG_EINVAL; + } + + err = ftx1_get_tx_split(rig, &is_split); + if (err != RIG_OK) + { + return err; + } + + *split = is_split; + return RIG_OK; +} + +static int ftx1_set_split(RIG *rig, vfo_t vfo, split_t split) +{ + int err; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + if (split == RIG_SPLIT_ON) + { + err = newcat_set_tx_vfo(rig, RIG_VFO_B); + } + else + { + err = newcat_set_tx_vfo(rig, RIG_VFO_A); + } + + return err; +} + +/* Tuning step functions */ +static int ftx1_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) +{ + // FTX-1 doesn't have a direct tuning step query command + // Return a default value + *ts = 100; + return RIG_OK; +} + +static int ftx1_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) +{ + // FTX-1 doesn't have a direct tuning step set command + // This would need to be implemented via mode-specific commands + return -RIG_ENIMPL; +} + +/* + * FTX-1 specific power control function + * The FTX-1 uses PC command with format: PC[amp][power] where: + * amp: 1 = radio only, 2 = amplifier + * power: 3-digit percentage (005-010 for radio, 005-100 for amp) + */ +int ftx1_set_power_control(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; + int amp_setting = 2; // Default to amp on (2) + int power_percent; + + ENTERFUNC; + + // Only handle RIG_LEVEL_RFPOWER + if (level != RIG_LEVEL_RFPOWER) + { + // For other levels, use the standard newcat function + return newcat_set_level(rig, vfo, level, val); + } + + // Convert power value (0.0-1.0) to percentage (0-100) + power_percent = (int)(val.f * 100.0f + 0.5f); + + // Ensure power is within valid range for amp (5-100) + if (power_percent < 5) power_percent = 5; + if (power_percent > 100) power_percent = 100; + + // Format: PC[amp][power] where amp=2 for amplifier, power=3 digits + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PC%d%03d%c", amp_setting, power_percent, cat_term); + + rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); + + RETURNFUNC(newcat_set_cmd(rig)); +} + +/* + * FTX-1 specific power reading function + * The FTX-1 returns PC command responses in format: PC[amp][power] where: + * amp: 1 = radio only, 2 = amplifier + * power: 3-digit percentage (005-010 for radio, 005-100 for amp) + */ +int ftx1_get_power_control(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +{ + struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; + int amp_setting, power_percent; + char response[16]; + int err; + + ENTERFUNC; + + // Only handle RIG_LEVEL_RFPOWER + if (level != RIG_LEVEL_RFPOWER) + { + // For other levels, use the standard newcat function + return newcat_get_level(rig, vfo, level, val); + } + + // Send PC; command to get current power setting + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PC%c", cat_term); + + if (RIG_OK != (err = newcat_get_cmd(rig))) + { + RETURNFUNC(err); + } + + // Parse response like "PC2075;" or "PC1004;" + // Extract the numeric part (2075 or 1004) + strncpy(response, priv->ret_data, sizeof(response) - 1); + response[sizeof(response) - 1] = '\0'; + + // Remove "PC" prefix and ";" suffix + if (strlen(response) >= 4 && strncmp(response, "PC", 2) == 0) + { + char *numeric_part = response + 2; // Skip "PC" + char *semicolon = strchr(numeric_part, ';'); + if (semicolon) *semicolon = '\0'; + + if (strlen(numeric_part) == 4) + { + amp_setting = numeric_part[0] - '0'; // First digit (1 or 2) + power_percent = atoi(numeric_part + 1); // Last 3 digits + + // Convert to 0.0-1.0 range + val->f = (float)power_percent / 100.0f; + + rig_debug(RIG_DEBUG_TRACE, "%s: response=%s, amp=%d, power=%d, val=%.3f\n", + __func__, response, amp_setting, power_percent, val->f); + + RETURNFUNC(RIG_OK); + } + } + + // If parsing failed, return error + RETURNFUNC(-RIG_EPROTO); +} + +/* + * FTX-1 specific frequency setting function + * The FTX-1 requires FA command with format: FA[11 digits]; where: + * frequency is formatted as 11 digits with leading zeros + * e.g., FA007200000; for 7.2 MHz + */ +int ftx1_set_freq(RIG *rig, vfo_t vfo, freq_t freq) +{ + struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; + char c; + int err; + + ENTERFUNC; + + // Determine VFO letter (A or B) + if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) + { + c = 'A'; + } + else if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) + { + c = 'B'; + } + else + { + // For other VFOs, default to A + c = 'A'; + } + + // Format: F[VFO][10 digits]; where 10 digits include leading zeros + // Radio returns: FA028100000; (10 digits after FA) + // We should send: FA028200000; (10 digits after FA, not 11) + // The frequency needs to be formatted as 10 digits with proper leading zeros + char freq_str[16]; + SNPRINTF(freq_str, sizeof(freq_str), "%09"PRIll, (int64_t)freq); + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "F%c%s%c", c, freq_str, cat_term); + + rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); + + RETURNFUNC(newcat_set_cmd(rig)); } \ No newline at end of file diff --git a/rigs/yaesu/ftx1.h b/rigs/yaesu/ftx1.h index 142d93b46..efbfa37dd 100644 --- a/rigs/yaesu/ftx1.h +++ b/rigs/yaesu/ftx1.h @@ -64,11 +64,11 @@ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|\ - RIG_FUNC_TUNER|RIG_FUNC_APF) + RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_MUTE) #define FTX1_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ - RIG_OP_TO_VFO|RIG_OP_FROM_VFO) + RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_MCL) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FTX1_RFPOWER_METER_CAL \ @@ -192,4 +192,22 @@ typedef struct char terminator; /* ';' */ } ftx1info; +/* Function prototypes for new commands */ +static int ftx1_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); +static int ftx1_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); +static int ftx1_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); +static int ftx1_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); +static int ftx1_get_split(RIG *rig, vfo_t vfo, split_t *split); +static int ftx1_set_split(RIG *rig, vfo_t vfo, split_t split); +static int ftx1_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); +static int ftx1_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); +static int ftx1_handle_cat_error(RIG *rig, const char *response); + +/* FTX-1 specific power control function */ +int ftx1_set_power_control(RIG *rig, vfo_t vfo, setting_t level, value_t val); +int ftx1_get_power_control(RIG *rig, vfo_t vfo, setting_t level, value_t *val); + +/* FTX-1 specific frequency setting function */ +int ftx1_set_freq(RIG *rig, vfo_t vfo, freq_t freq); + #endif /* _FTX1_H */ \ No newline at end of file diff --git a/rigs/yaesu/newcat.c b/rigs/yaesu/newcat.c index ccdc9c605..31ce67d01 100644 --- a/rigs/yaesu/newcat.c +++ b/rigs/yaesu/newcat.c @@ -6,6 +6,7 @@ * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2010 * (C) David Fannin (kk6df at arrl.net) + * (C) Jeremy Miller KO4SSD 2025 (ko4ssd at ko4ssd.com) * * This shared library provides an API for communicating * via serial interface to any newer Yaesu radio using the @@ -248,23 +249,23 @@ static ncboolean is_ftdx9000Old; static const yaesu_newcat_commands_t valid_commands[] = { /* Command FT-450 FT-950 FT-891 FT-991 FT-2000 FT-9000 FT-5000 FT-1200 FT-3000 FTDX101D FTDX10 FTDX101MP FT710 FTX1 FT9000Old*/ - {"AB", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + {"AB", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE }, {"AC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AM", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AN", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE }, - {"AO", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, - {"BA", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"AO", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, + {"BA", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BC", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, - {"BM", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"BM", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BP", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BU", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BY", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, - {"CF", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE }, + {"CF", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE }, {"CH", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CN", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CO", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, @@ -274,7 +275,7 @@ static const yaesu_newcat_commands_t valid_commands[] = {"DN", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"DP", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"DS", TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, - {"DT", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"DT", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"ED", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"EK", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE }, {"EM", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE }, @@ -284,7 +285,7 @@ static const yaesu_newcat_commands_t valid_commands[] = {"FA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FK", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, - {"FN", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"FN", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FR", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE }, {"FT", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, @@ -300,7 +301,7 @@ static const yaesu_newcat_commands_t valid_commands[] = {"LK", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"LM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MA", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, - {"MB", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"MB", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, @@ -308,10 +309,10 @@ static const yaesu_newcat_commands_t valid_commands[] = {"ML", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, - {"MT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"MT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MW", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MX", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, - {"NA", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"NA", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"NB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"NL", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"NR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, @@ -323,8 +324,8 @@ static const yaesu_newcat_commands_t valid_commands[] = {"PL", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PR", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, - {"QI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, - {"QR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + {"QI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"QR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"QS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, @@ -345,13 +346,13 @@ static const yaesu_newcat_commands_t valid_commands[] = {"SH", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SQ", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, - {"SS", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"SS", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, // ST command has two meanings Step or Split Status // If new rig is added that has ST ensure it means Split // Otherwise modify newcat_(set|get)_split - {"ST", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"ST", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SV", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, - {"SY", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE}, + {"SY", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE }, {"TS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"TX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"UL", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, @@ -361,12 +362,12 @@ static const yaesu_newcat_commands_t valid_commands[] = {"VG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"VM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"VR", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE }, - {"VS", TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, - {"VT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE }, - {"VV", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE }, + {"VS", TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + {"VT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE }, + {"VV", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE }, {"VX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"XT", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE }, - {"ZI", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, + {"ZI", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, } ; int valid_commands_count = sizeof(valid_commands) / sizeof( diff --git a/rigs/yaesu/yaesu.c b/rigs/yaesu/yaesu.c index ac9923ab6..db9916d2b 100644 --- a/rigs/yaesu/yaesu.c +++ b/rigs/yaesu/yaesu.c @@ -2,6 +2,7 @@ * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * yaesu.c - (C) Stephane Fillod 2001-2010 + * (C) Jeremy Miller KO4SSD 2025 (ko4ssd at ko4ssd.com) * * This shared library provides an API for communicating * via serial interface to a Yaesu rig diff --git a/rigs/yaesu/yaesu.h b/rigs/yaesu/yaesu.h index 049e2f678..7685d3664 100644 --- a/rigs/yaesu/yaesu.h +++ b/rigs/yaesu/yaesu.h @@ -3,6 +3,7 @@ * * yaesu.h - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2001-2010 + * (C) Jeremy Miller KO4SSD 2025 (ko4ssd at ko4ssd.com) * * Common yaesu declarations for hamlib * diff --git a/tests/Makefile.am b/tests/Makefile.am index c120165ff..141c2cab4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -17,7 +17,7 @@ DISTCLEANFILES = rigctl.log rigctl.sum testbcd.log testbcd.sum bin_PROGRAMS = rigctl rigctld rigmem rigsmtr rigswr rotctl rotctld rigctlcom rigctltcp rigctlsync ampctl ampctld rigtestmcast rigtestmcastrx $(TESTLIBUSB) rigfreqwalk #check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie testgrid testsecurity -check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie testgrid hamlibmodels testmW2power test2038 +check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie testgrid hamlibmodels testmW2power test2038 test_ftx1 RIGCOMMONSRC = rigctl_parse.c rigctl_parse.h dumpcaps.c dumpstate.c uthash.h rig_tests.c rig_tests.h dumpcaps.h ROTCOMMONSRC = rotctl_parse.c rotctl_parse.h dumpcaps_rot.c uthash.h dumpcaps_rot.h @@ -39,6 +39,8 @@ if HAVE_LIBUSB rigtestlibusb_SOURCES = rigtestlibusb.c endif +test_ftx1_SOURCES = test_ftx1.c + # include generated include files ahead of any in sources rigctl_CPPFLAGS = -I$(top_builddir)/tests -I$(top_builddir)/src -I$(srcdir) -I$(top_builddir)/security $(AM_CPPFLAGS)