diff --git a/rigs/yaesu/ftx1.c b/rigs/yaesu/ftx1.c index 96e5986a7..45403dba3 100644 --- a/rigs/yaesu/ftx1.c +++ b/rigs/yaesu/ftx1.c @@ -112,6 +112,7 @@ extern int ftx1_stop_morse_func(RIG *rig, vfo_t vfo); extern int ftx1_wait_morse_func(RIG *rig, vfo_t vfo); extern int ftx1_set_trn_func(RIG *rig, int trn); extern int ftx1_get_trn_func(RIG *rig, int *trn); +extern int ftx1_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); /* Externs from ftx1_mem.c */ extern int ftx1_set_mem(RIG *rig, vfo_t vfo, int ch); @@ -140,6 +141,8 @@ extern int ftx1_set_freq(RIG *rig, vfo_t vfo, freq_t freq); extern int ftx1_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); extern int ftx1_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); extern int ftx1_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift); +extern int ftx1_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); +extern int ftx1_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs); /* Externs from ftx1_vfo.c */ extern int ftx1_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); @@ -513,7 +516,7 @@ struct rig_caps ftx1_caps = { .status = RIG_STATUS_BETA, /* Update to stable once complete */ .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, - .dcd_type = RIG_DCD_NONE, /* FTX-1 CAT has no squelch status command */ + .dcd_type = RIG_DCD_RIG, /* FTX-1 RI command P8 provides squelch status */ .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, @@ -528,10 +531,11 @@ struct rig_caps ftx1_caps = { /* Note: ARO, FAGC, DIVERSITY return '?' from FTX-1 firmware - not supported */ /* DUAL_WATCH uses FR command for dual/single receive mode */ /* Contour (CO command) is FTX-1 specific - handle via ext_level */ + /* Note: NA command (narrow filter) available via ftx1_set_na_helper/ftx1_get_na_helper but no RIG_FUNC_NAR exists in Hamlib */ .has_get_func = RIG_FUNC_COMP | RIG_FUNC_VOX | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_SBKIN | RIG_FUNC_FBKIN | RIG_FUNC_NB | RIG_FUNC_NR | RIG_FUNC_MN | RIG_FUNC_LOCK | RIG_FUNC_MON | RIG_FUNC_TUNER | RIG_FUNC_RIT | RIG_FUNC_XIT | RIG_FUNC_APF | RIG_FUNC_ANF | RIG_FUNC_DUAL_WATCH, .has_set_func = RIG_FUNC_COMP | RIG_FUNC_VOX | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_SBKIN | RIG_FUNC_FBKIN | RIG_FUNC_NB | RIG_FUNC_NR | RIG_FUNC_MN | RIG_FUNC_LOCK | RIG_FUNC_MON | RIG_FUNC_TUNER | RIG_FUNC_RIT | RIG_FUNC_XIT | RIG_FUNC_APF | RIG_FUNC_ANF | RIG_FUNC_DUAL_WATCH, - .has_get_level = RIG_LEVEL_AF | RIG_LEVEL_RF | RIG_LEVEL_SQL | RIG_LEVEL_IF | RIG_LEVEL_APF | RIG_LEVEL_NB | RIG_LEVEL_NR | RIG_LEVEL_PBT_IN | RIG_LEVEL_PBT_OUT | RIG_LEVEL_RFPOWER | RIG_LEVEL_MICGAIN | RIG_LEVEL_KEYSPD | RIG_LEVEL_NOTCHF | RIG_LEVEL_COMP | RIG_LEVEL_AGC | RIG_LEVEL_BKINDL | RIG_LEVEL_BALANCE | RIG_LEVEL_METER | RIG_LEVEL_VOXGAIN | RIG_LEVEL_VOXDELAY | RIG_LEVEL_ANTIVOX | RIG_LEVEL_RAWSTR | RIG_LEVEL_SWR | RIG_LEVEL_ALC | RIG_LEVEL_STRENGTH | RIG_LEVEL_ATT | RIG_LEVEL_PREAMP | RIG_LEVEL_MONITOR_GAIN, - .has_set_level = RIG_LEVEL_SET(RIG_LEVEL_AF | RIG_LEVEL_RF | RIG_LEVEL_SQL | RIG_LEVEL_IF | RIG_LEVEL_APF | RIG_LEVEL_NB | RIG_LEVEL_NR | RIG_LEVEL_PBT_IN | RIG_LEVEL_PBT_OUT | RIG_LEVEL_RFPOWER | RIG_LEVEL_MICGAIN | RIG_LEVEL_KEYSPD | RIG_LEVEL_NOTCHF | RIG_LEVEL_COMP | RIG_LEVEL_AGC | RIG_LEVEL_BKINDL | RIG_LEVEL_BALANCE | RIG_LEVEL_METER | RIG_LEVEL_VOXGAIN | RIG_LEVEL_VOXDELAY | RIG_LEVEL_ANTIVOX | RIG_LEVEL_RAWSTR | RIG_LEVEL_SWR | RIG_LEVEL_ALC | RIG_LEVEL_STRENGTH | RIG_LEVEL_ATT | RIG_LEVEL_PREAMP | RIG_LEVEL_MONITOR_GAIN), + .has_get_level = RIG_LEVEL_AF | RIG_LEVEL_RF | RIG_LEVEL_SQL | RIG_LEVEL_IF | RIG_LEVEL_APF | RIG_LEVEL_NB | RIG_LEVEL_NR | RIG_LEVEL_PBT_IN | RIG_LEVEL_PBT_OUT | RIG_LEVEL_RFPOWER | RIG_LEVEL_MICGAIN | RIG_LEVEL_KEYSPD | RIG_LEVEL_NOTCHF | RIG_LEVEL_COMP | RIG_LEVEL_AGC | RIG_LEVEL_BKINDL | RIG_LEVEL_BALANCE | RIG_LEVEL_METER | RIG_LEVEL_VOXGAIN | RIG_LEVEL_VOXDELAY | RIG_LEVEL_ANTIVOX | RIG_LEVEL_RAWSTR | RIG_LEVEL_SWR | RIG_LEVEL_ALC | RIG_LEVEL_STRENGTH | RIG_LEVEL_ATT | RIG_LEVEL_PREAMP | RIG_LEVEL_MONITOR_GAIN | RIG_LEVEL_CWPITCH, + .has_set_level = RIG_LEVEL_SET(RIG_LEVEL_AF | RIG_LEVEL_RF | RIG_LEVEL_SQL | RIG_LEVEL_IF | RIG_LEVEL_APF | RIG_LEVEL_NB | RIG_LEVEL_NR | RIG_LEVEL_PBT_IN | RIG_LEVEL_PBT_OUT | RIG_LEVEL_RFPOWER | RIG_LEVEL_MICGAIN | RIG_LEVEL_KEYSPD | RIG_LEVEL_NOTCHF | RIG_LEVEL_COMP | RIG_LEVEL_AGC | RIG_LEVEL_BKINDL | RIG_LEVEL_BALANCE | RIG_LEVEL_METER | RIG_LEVEL_VOXGAIN | RIG_LEVEL_VOXDELAY | RIG_LEVEL_ANTIVOX | RIG_LEVEL_RAWSTR | RIG_LEVEL_SWR | RIG_LEVEL_ALC | RIG_LEVEL_STRENGTH | RIG_LEVEL_ATT | RIG_LEVEL_PREAMP | RIG_LEVEL_MONITOR_GAIN | RIG_LEVEL_CWPITCH), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { @@ -696,6 +700,7 @@ struct rig_caps ftx1_caps = { .get_vfo = ftx1_get_vfo, .set_ptt = ftx1_set_ptt_func, .get_ptt = ftx1_get_ptt_func, + .get_dcd = ftx1_get_dcd, /* RI command P8 provides squelch/DCD status */ .set_powerstat = ftx1_set_powerstat_func, .get_powerstat = ftx1_get_powerstat_func, .set_func = ftx1_set_func, @@ -739,6 +744,8 @@ struct rig_caps ftx1_caps = { .get_xit = ftx1_get_xit, .set_rptr_shift = ftx1_set_rptr_shift, .get_rptr_shift = ftx1_get_rptr_shift, + .set_rptr_offs = ftx1_set_rptr_offs, + .get_rptr_offs = ftx1_get_rptr_offs, .set_split_vfo = ftx1_set_split_vfo, .get_split_vfo = ftx1_get_split_vfo, .set_split_freq = ftx1_set_split_freq, diff --git a/rigs/yaesu/ftx1/ftx1_freq.c b/rigs/yaesu/ftx1/ftx1_freq.c index bfce5f887..7e6800421 100644 --- a/rigs/yaesu/ftx1/ftx1_freq.c +++ b/rigs/yaesu/ftx1/ftx1_freq.c @@ -291,3 +291,151 @@ int ftx1_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift) return RIG_OK; } +/* + * ============================================================================= + * Repeater Offset Frequency Functions + * ============================================================================= + * FTX-1 stores repeater offset frequencies in EX menu items per band: + * EX010316 (TOK_FM_RPT_SHIFT_28) - 28 MHz band (0-1000 kHz) + * EX010317 (TOK_FM_RPT_SHIFT_50) - 50 MHz band (0-4000 kHz) + * EX010318 (TOK_FM_RPT_SHIFT_144) - 144 MHz band (0-100 x 10 kHz = 0-1000 kHz) + * EX010319 (TOK_FM_RPT_SHIFT_430) - 430 MHz band (0-100 x 100 kHz = 0-10000 kHz) + * + * The menu values are in different units per band. + */ + +#include "../ftx1.h" +#include "ftx1_menu.h" + +/* + * ftx1_get_band_offset_token - Get menu token for current band's repeater offset + * + * Returns the token for the appropriate band, or 0 if not applicable. + * Also returns the multiplier to convert menu value to Hz. + */ +static hamlib_token_t ftx1_get_band_offset_token(freq_t freq, int *multiplier) +{ + if (freq >= MHz(420) && freq <= MHz(470)) + { + /* 430 MHz band - menu value is in 100 kHz units */ + *multiplier = 100000; + return TOK_FM_RPT_SHIFT_430; + } + else if (freq >= MHz(144) && freq <= MHz(148)) + { + /* 144 MHz band - menu value is in 10 kHz units */ + *multiplier = 10000; + return TOK_FM_RPT_SHIFT_144; + } + else if (freq >= MHz(50) && freq <= MHz(54)) + { + /* 50 MHz band - menu value is in kHz */ + *multiplier = 1000; + return TOK_FM_RPT_SHIFT_50; + } + else if (freq >= MHz(28) && freq <= MHz(30)) + { + /* 28 MHz band - menu value is in kHz */ + *multiplier = 1000; + return TOK_FM_RPT_SHIFT_28; + } + + /* Band doesn't support repeater offset */ + *multiplier = 0; + return 0; +} + +/* + * ftx1_set_rptr_offs - Set repeater offset frequency + * + * Sets the offset for the current band via EX menu. + * Requires reading current frequency to determine which band's offset to set. + */ +int ftx1_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) +{ + int ret; + freq_t freq; + hamlib_token_t token; + int multiplier; + value_t val; + + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s offs=%ld\n", + __func__, rig_strvfo(vfo), offs); + + /* Get current frequency to determine band */ + ret = ftx1_get_freq(rig, vfo, &freq); + if (ret != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s: failed to get frequency\n", __func__); + return ret; + } + + /* Get appropriate token for this band */ + token = ftx1_get_band_offset_token(freq, &multiplier); + if (token == 0 || multiplier == 0) + { + rig_debug(RIG_DEBUG_WARN, "%s: band at %.0f Hz doesn't support repeater offset\n", + __func__, freq); + return -RIG_ENAVAIL; + } + + /* Convert Hz offset to menu value */ + val.i = (int)(offs / multiplier); + + rig_debug(RIG_DEBUG_VERBOSE, "%s: freq=%.0f token=0x%lx val=%d (offs=%ld, mult=%d)\n", + __func__, freq, (unsigned long)token, val.i, offs, multiplier); + + /* Set via menu system */ + return ftx1_menu_set_token(rig, token, val); +} + +/* + * ftx1_get_rptr_offs - Get repeater offset frequency + * + * Gets the offset for the current band via EX menu. + * Requires reading current frequency to determine which band's offset to read. + */ +int ftx1_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs) +{ + int ret; + freq_t freq; + hamlib_token_t token; + int multiplier; + value_t val; + + rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); + + /* Get current frequency to determine band */ + ret = ftx1_get_freq(rig, vfo, &freq); + if (ret != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s: failed to get frequency\n", __func__); + return ret; + } + + /* Get appropriate token for this band */ + token = ftx1_get_band_offset_token(freq, &multiplier); + if (token == 0 || multiplier == 0) + { + rig_debug(RIG_DEBUG_WARN, "%s: band at %.0f Hz doesn't support repeater offset\n", + __func__, freq); + *offs = 0; + return RIG_OK; /* Return 0 offset for bands without repeater */ + } + + /* Get via menu system */ + ret = ftx1_menu_get_token(rig, token, &val); + if (ret != RIG_OK) + { + return ret; + } + + /* Convert menu value to Hz offset */ + *offs = (shortfreq_t)val.i * multiplier; + + rig_debug(RIG_DEBUG_VERBOSE, "%s: freq=%.0f token=0x%lx val=%d offs=%ld\n", + __func__, freq, (unsigned long)token, val.i, *offs); + + return RIG_OK; +} + diff --git a/rigs/yaesu/ftx1/ftx1_func.c b/rigs/yaesu/ftx1/ftx1_func.c index 66fa92180..2d853f685 100644 --- a/rigs/yaesu/ftx1/ftx1_func.c +++ b/rigs/yaesu/ftx1/ftx1_func.c @@ -224,6 +224,7 @@ int ftx1_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) case RIG_FUNC_DUAL_WATCH: /* FTX-1: FR command controls dual/single receive mode */ return ftx1_set_dual_receive(rig, status); + /* Note: NA command (narrow) available via ftx1_set_na_helper but no RIG_FUNC_NAR in Hamlib */ /* Note: Contour (CO command) not exposed as RIG_FUNC_CONTOUR doesn't exist in Hamlib */ default: return newcat_set_func(rig, vfo, func, status); @@ -299,6 +300,7 @@ int ftx1_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) case RIG_FUNC_DUAL_WATCH: /* FTX-1: FR command controls dual/single receive mode */ return ftx1_get_dual_receive(rig, status); + /* Note: NA command (narrow) available via ftx1_get_na_helper but no RIG_FUNC_NAR in Hamlib */ /* Note: Contour (CO command) not exposed as RIG_FUNC_CONTOUR doesn't exist in Hamlib */ default: return newcat_get_func(rig, vfo, func, status); diff --git a/rigs/yaesu/ftx1/ftx1_menu.c b/rigs/yaesu/ftx1/ftx1_menu.c index 3655d9c61..eb6aba97e 100644 --- a/rigs/yaesu/ftx1/ftx1_menu.c +++ b/rigs/yaesu/ftx1/ftx1_menu.c @@ -335,6 +335,8 @@ static const struct ftx1_menu_item ftx1_menu_table[] = { { TOK_APRS_AF_MUTE, "APRS_AF_MUTE", 1, 0, 1, 0 }, { TOK_APRS_TX_DELAY, "APRS_TX_DELAY", 1, 0, 6, 0 }, { TOK_APRS_CALLSIGN, "APRS_CALLSIGN", 8, 0, 0, FTX1_MENU_FLAG_STRING }, + /* Items 06-08 don't exist */ + { TOK_APRS_DEST, "APRS_DEST", 6, 0, 0, FTX1_MENU_FLAG_STRING }, /* Fixed: APYX01 */ /* EX0602: MSG TEMPLATE */ { TOK_APRS_MSG_TEXT1, "APRS_MSG_TEXT1", 16, 0, 0, FTX1_MENU_FLAG_STRING }, diff --git a/rigs/yaesu/ftx1/ftx1_menu.h b/rigs/yaesu/ftx1/ftx1_menu.h index 96099cc13..b3c7a086c 100644 --- a/rigs/yaesu/ftx1/ftx1_menu.h +++ b/rigs/yaesu/ftx1/ftx1_menu.h @@ -356,6 +356,8 @@ #define TOK_APRS_AF_MUTE FTX1_TOKEN(6, 1, 3) #define TOK_APRS_TX_DELAY FTX1_TOKEN(6, 1, 4) #define TOK_APRS_CALLSIGN FTX1_TOKEN(6, 1, 5) +/* Note: Items 06-08 don't exist per CAT manual */ +#define TOK_APRS_DEST FTX1_TOKEN(6, 1, 9) /* APRS DESTINATION (fixed: APYX01) */ /* EX0602: MSG TEMPLATE */ #define TOK_APRS_MSG_TEXT1 FTX1_TOKEN(6, 2, 1) diff --git a/rigs/yaesu/ftx1/ftx1_readme.txt b/rigs/yaesu/ftx1/ftx1_readme.txt index 0a25d1e4b..70e9ce0d0 100644 --- a/rigs/yaesu/ftx1/ftx1_readme.txt +++ b/rigs/yaesu/ftx1/ftx1_readme.txt @@ -36,6 +36,18 @@ VFO Commands (ftx1_vfo.c): Frequency Commands (ftx1_freq.c): FA P1...P9; - VFO-A Frequency (9-digit Hz, e.g., FA014250000;) [WORKING] FB P1...P9; - VFO-B Frequency (9-digit Hz) [WORKING] + OS P1 P2; - Offset Shift (repeater direction) [WORKING - set/read] + P1=VFO (0=MAIN, 1=SUB), P2=Shift (0=Simplex, 1=Plus, 2=Minus, 3=ARS) + +Repeater Offset Frequency (ftx1_freq.c): + Repeater offset values are stored per-band in EX menu items: + EX010316 (TOK_FM_RPT_SHIFT_28) - 28 MHz band (0-1000 kHz) + EX010317 (TOK_FM_RPT_SHIFT_50) - 50 MHz band (0-4000 kHz) + EX010318 (TOK_FM_RPT_SHIFT_144) - 144 MHz band (0-1000 kHz, in 10kHz units) + EX010319 (TOK_FM_RPT_SHIFT_430) - 430 MHz band (0-10000 kHz, in 100kHz units) + + ftx1_set_rptr_offs() and ftx1_get_rptr_offs() automatically detect the current + band from VFO frequency and access the appropriate menu token. RIT/XIT Clarifier Commands (ftx1_clarifier.c): *** SPECIAL ACKNOWLEDGMENT - JEREMY MILLER (KO4SSD) *** @@ -435,7 +447,10 @@ Commands: Read: PB0; Response: PB0n (n=channel or 0 if stopped) PL P1; - Processor Level [WORKING - read-only] PR P1; - Processor on/off [WORKING - read-only] - RI P1; - RIT Information [WORKING - read-only] + RI; - Radio Information [WORKING - read-only, used for DCD/squelch status] + Response: RI P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13; + P8 = SQL status: 0=Closed (no signal), 1=Open (BUSY/signal present) + Used by ftx1_get_dcd() to report squelch/DCD state SF P1 P2; - Sub Dial (FUNC Knob) assignment [WORKING - read-only recommended] P1=VFO (0), P2=single hex char (0-H) 0=None, 7=Mic Gain, D=RF Power, G=CW Pitch, H=BK Delay @@ -708,10 +723,13 @@ Supported Features - Manual/auto notch filter - Beat cancel and contour controls - CW keyer with memories (1-5) +- CW pitch adjustment (300-1050 Hz via KP command) - VOX with adjustable gain and delay - Memory channels (1-99) plus PMS (100-117) - Antenna tuner control - S-meter, SWR, ALC, power meter readings +- DCD (squelch status) via RI command P8 +- Repeater shift direction and offset frequency (per-band via EX menu) Tuner Control ------------- @@ -752,20 +770,20 @@ Header File: Source Files: ftx1.c - Main driver, rig_caps, open/close, SPA-1 detection ftx1_vfo.c - VFO select (VS), split (ST/FT), VFO operations (AB/BA/SV) - ftx1_freq.c - Frequency get/set (FA/FB) + ftx1_freq.c - Frequency (FA/FB), repeater shift (OS), repeater offset (EX menu) ftx1_mode.c - Mode documentation (delegates to newcat) ftx1_audio.c - AF/RF/Mic gain (AG/RG/MG), power (PC), meters (SM/RM), AGC (GT) ftx1_clarifier.c - RIT/XIT using RC/TC commands (Jeremy Miller KO4SSD - PR #1826) ftx1_func.c - Central dispatcher for func/level operations ftx1_info.c - Radio info (ID/IF/OI), AI mode, IF shift (IS), date/time (DT) ftx1_mem.c - Memory operations (MC/MR/MW/MT/MZ/MA/MB/AM/BM/VM/CH) - ftx1_tx.c - PTT (TX), VOX (VX), tuner (AC), break-in (BI), power (PS) + ftx1_tx.c - PTT (TX), VOX (VX), tuner (AC), break-in (BI), power (PS), DCD (RI) ftx1_cw.c - CW keyer (KS/KP/KR/KY/KM/SD/CS) ftx1_ctcss.c - CTCSS/DCS tone control (CN/CT/DC) ftx1_noise.c - Noise blanker (NL), noise reduction (RL) ftx1_filter.c - Notch (BP), contour/APF (CO), beat cancel (BC) ftx1_preamp.c - Preamp (PA), attenuator (RA) - ftx1_scan.c - Scan (SC), band select (BS), tuning step (TS), zero-in (ZI) + ftx1_scan.c - Scan (SC), band select (BS), band up/down (BU/BD), tuning step (TS), zero-in (ZI) ftx1_ext.c - Extended menu basics (EX), spectrum scope (SS), encoder offset (EO) ftx1_menu.c - Complete EX menu (~250 items): all 11 groups, set/get, ext_parm ftx1_menu.h - EX menu token definitions (TOK_*), item structures, flags @@ -773,6 +791,26 @@ Source Files: ================================================================================ REVISION HISTORY ================================================================================ +2025-12-19 Gap fixes and additional capability support + - Added DCD (squelch status) support via RI command P8 + * Implemented ftx1_get_dcd() in ftx1_tx.c + * Changed dcd_type from RIG_DCD_NONE to RIG_DCD_RIG + * RI command returns 13 parameters, P8 is SQL status (0=closed, 1=open) + - Added RIG_LEVEL_CWPITCH to has_get_level/has_set_level + * Implementation already existed via KP command (300-1050 Hz) + * Now properly advertised in rig_caps + - Added repeater offset frequency support (set_rptr_offs/get_rptr_offs) + * Implemented in ftx1_freq.c using per-band EX menu tokens + * TOK_FM_RPT_SHIFT_28/50/144/430 for band-specific offsets + * Auto-detects band from VFO frequency + - Implemented RIG_OP_BAND_UP and RIG_OP_BAND_DOWN + * ftx1_band_up() uses BU0; command + * ftx1_band_down() uses BD0; command + * Cycles through amateur bands on MAIN VFO + - Note: NA (narrow filter) helpers exist but Hamlib has no RIG_FUNC_NAR + * ftx1_set_na_helper() and ftx1_get_na_helper() available internally + * Cannot be exposed via standard Hamlib func interface + 2025-12-19 Implemented complete EX menu support (~250 menu items) - Created ftx1_menu.h with token definitions for all EX commands Token encoding: 0xGGSSII maps directly to EX group/section/item diff --git a/rigs/yaesu/ftx1/ftx1_scan.c b/rigs/yaesu/ftx1/ftx1_scan.c index 7895e3183..f494e1090 100644 --- a/rigs/yaesu/ftx1/ftx1_scan.c +++ b/rigs/yaesu/ftx1/ftx1_scan.c @@ -24,6 +24,8 @@ * CAT Commands in this file: * SC P1; - Scan Control (0=stop, 1=up, 2=down) * BS P1P2; - Band Select (P1P2=band code) + * BU P1; - Band Up (P1=VFO, cycles to higher band) + * BD P1; - Band Down (P1=VFO, cycles to lower band) * UP; - Frequency/Channel Up * DN; - Frequency/Channel Down * TS P1P2; - Tuning Step (00-14 code for step size) @@ -235,6 +237,36 @@ int ftx1_freq_down(RIG *rig) return newcat_set_cmd(rig); } +/* + * Band Up (BU P1;) + * CAT command: BU P1; (P1=0 for MAIN VFO) + * Cycles to the next higher amateur band + */ +int ftx1_band_up(RIG *rig) +{ + struct newcat_priv_data *priv = STATE(rig)->priv; + + rig_debug(RIG_DEBUG_VERBOSE, "%s\n", __func__); + + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BU0;"); + return newcat_set_cmd(rig); +} + +/* + * Band Down (BD P1;) + * CAT command: BD P1; (P1=0 for MAIN VFO) + * Cycles to the next lower amateur band + */ +int ftx1_band_down(RIG *rig) +{ + struct newcat_priv_data *priv = STATE(rig)->priv; + + rig_debug(RIG_DEBUG_VERBOSE, "%s\n", __func__); + + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BD0;"); + return newcat_set_cmd(rig); +} + /* Set Tuning Step (TS P1P2;) */ int ftx1_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { @@ -302,10 +334,9 @@ int ftx1_vfo_op_scan(RIG *rig, vfo_t vfo, vfo_op_t op) case RIG_OP_DOWN: return ftx1_freq_down(rig); case RIG_OP_BAND_UP: - /* Not directly supported, could cycle bands */ - return -RIG_ENIMPL; + return ftx1_band_up(rig); case RIG_OP_BAND_DOWN: - return -RIG_ENIMPL; + return ftx1_band_down(rig); default: return -RIG_EINVAL; } diff --git a/rigs/yaesu/ftx1/ftx1_tx.c b/rigs/yaesu/ftx1/ftx1_tx.c index deb2d32a7..c0bafb4c0 100644 --- a/rigs/yaesu/ftx1/ftx1_tx.c +++ b/rigs/yaesu/ftx1/ftx1_tx.c @@ -522,3 +522,63 @@ int ftx1_get_tx_watch(RIG *rig, int *status) return RIG_OK; } + +/* + * ============================================================================= + * RI Command: Read Radio Information (for DCD/Squelch status) + * ============================================================================= + * CAT format: RI; + * Response: RI P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13; + * + * P8 = SQL (Squelch) status: + * 0 = SQL Closed (no signal / below threshold) + * 1 = SQL Open (BUSY - signal present / above threshold) + * + * This is used for DCD (Data Carrier Detect) functionality. + */ + +/* + * ftx1_get_dcd - Get DCD (squelch) status via RI command P8 + * + * Returns RIG_DCD_ON when squelch is open (signal present), + * RIG_DCD_OFF when squelch is closed (no signal). + */ +int ftx1_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) +{ + struct newcat_priv_data *priv = STATE(rig)->priv; + int ret; + int p1, p2, p3, p4, p5, p6, p7, p8; + + (void)vfo; /* FTX-1 RI command returns overall status, not per-VFO */ + + rig_debug(RIG_DEBUG_VERBOSE, "%s\n", __func__); + + SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RI;"); + + ret = newcat_get_cmd(rig); + if (ret != RIG_OK) + { + return ret; + } + + /* + * Response format: RI P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13; + * Each P is a single digit. We need P8 (SQL status). + * Parse 8 digits to get to P8. + */ + if (sscanf(priv->ret_data + 2, "%1d%1d%1d%1d%1d%1d%1d%1d", + &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8) != 8) + { + rig_debug(RIG_DEBUG_ERR, "%s: failed to parse '%s'\n", + __func__, priv->ret_data); + return -RIG_EPROTO; + } + + /* P8: 0=SQL Closed (no signal), 1=SQL Open (BUSY/signal present) */ + *dcd = (p8 == 1) ? RIG_DCD_ON : RIG_DCD_OFF; + + rig_debug(RIG_DEBUG_VERBOSE, "%s: P8(SQL)=%d dcd=%s\n", + __func__, p8, (*dcd == RIG_DCD_ON) ? "ON" : "OFF"); + + return RIG_OK; +}