[Hamlib-commits] Hamlib -- Ham radio control libraries branch Hamlib-4.5.5 updated. 4.5.4-63-g9bf80
Library to control radio transceivers and receivers
Brought to you by:
n0nb
From: n0nb <n0...@us...> - 2023-04-05 01:57:34
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Hamlib -- Ham radio control libraries". The branch, Hamlib-4.5.5 has been updated via 9bf8066b836399507e0ae5cbed3f6c07a16de938 (commit) via 4ab3aaf3588d92c9d1d116cfa48f747737c834f4 (commit) via ddf11623148650e91c88eee0f29dad116c53d50d (commit) via ceb51534c59a1da24c8720ebd3b4e14b5fc20f73 (commit) via bab6dbe548ac9f6f91c4367a260749ef9cb49873 (commit) via df70d0f9dac6f9e58c5e4fbfcf25d0268962e2d1 (commit) via 6595a2587c4403cfe736d11c0521bd019cafefd5 (commit) via c240bd1cd095a0fc5f2eed66481404cf30435b16 (commit) via ee987bc88e9712ade2bf4353e9bd50bccba50d54 (commit) via 7fa8b6889b1612e992f8d42a3293e63dd2e83f90 (commit) via e0af8c0a7a4c3a4d1d266705af46ced5f910ae2b (commit) via 3fa423c63dd19a47bd48cc60eac9b08f4a48caca (commit) via 9fc5ec5035921c174061bafcfb610cbf1f73ea46 (commit) via fe2ebcb06f83991f6c5f3057fb49adef59bf4ad3 (commit) via 4a08058186220b74f72d8e4beca3848dfe414ba5 (commit) via a73f8ae4825236b1e7160b7c2f1e7c39808a892a (commit) via a1abda197ed2a691d9834fb88331b30af72edd15 (commit) via 471a247a99bc2982211b935758ef54651fe14277 (commit) via fd05de48aac1bcd58bcc4a38b10cf50cf0dfd2c9 (commit) via c67f53ee7987cef3d0d1d0f3475849a62ece3e22 (commit) via d03cdcef83ce9ced5752e109513b59453fa4a53c (commit) via 38502218e1ca66b44dcfb235dba167378adbfdcb (commit) via e05f154a8db6c000674afd2dc03c1e0a47ccccff (commit) via d946b80a4dcb7bc99fda25eee1716a9ae15772a5 (commit) via 165b5514cd0ae2f0bf0511e56f909c57c0959117 (commit) via d47a0279c9204ecd73edb63485f192f4fc3ba498 (commit) via a3a1b4c6be38cffaa502c558fafdfb62678ee1b4 (commit) via 41c90b759e00b80431d45d0786d4421036be164e (commit) via c11955154573160e90d466a87425891650763332 (commit) via 252a0c2bd73daf1a1b75f2f1d205b237f1b10f3e (commit) via afb909271524c638b60c66b8906aeb8f198617cc (commit) via 1b7649d49e6bf33bc5a177711cdd1fea3cbbe0b8 (commit) via ccb879df9492d382a0bb87aebd6102f528c42eae (commit) via 9b3ee663fba2c25442811897a3fb73ec25416776 (commit) via 9ee5afbcf6a1326610114341f90c2c566950d203 (commit) via 1f25aab7858b4e7d8a681781accc93906e197448 (commit) via 5c21f0e790a1948e9a9a7c6cb465af1bac543272 (commit) via 73bbb072c14f62c629096e15a474d21393ad016e (commit) via de0c60563c7feafbd9d6a493bef770dadf5374ec (commit) via 8217088293483bb1f9966b35a91c1dc67bfa8187 (commit) via d82d2d35257d0bbdecd599dbb80d27bde8a0ac4a (commit) via 5b8621606f1af28f18180e03a962ed97742ef1e1 (commit) via 2a0145d77b87813274ec5609404a69b4914c891f (commit) from 88f6eb29a8d29900f8486f550566f6628a64c12b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9bf8066b836399507e0ae5cbed3f6c07a16de938 Author: Mike Black W9MDB <mdb...@ya...> Date: Thu Mar 30 22:28:09 2023 -0500 Add error message when rig is not turned on that mentions auto_power_on diff --git a/src/rig.c b/src/rig.c index efe2811c..c5352418 100644 --- a/src/rig.c +++ b/src/rig.c @@ -1266,7 +1266,12 @@ int HAMLIB_API rig_open(RIG *rig) powerstat_t powerflag; status = rig_get_powerstat(rig, &powerflag); - if (status == RIG_OK && powerflag == RIG_POWER_OFF && rig->state.auto_power_on == 0) { return (-RIG_EPOWER); } + if (status == RIG_OK && powerflag == RIG_POWER_OFF && rig->state.auto_power_on == 0) + { + rig_debug(RIG_DEBUG_ERR, "%s: rig power is off, use --set-conf=auto_power_on if power on is wanted\n", __func__); + + return (-RIG_EPOWER); + } // don't need auto_power_on if power is already on if (status == RIG_OK && powerflag == RIG_POWER_ON) { rig->state.auto_power_on = 0; } commit 4ab3aaf3588d92c9d1d116cfa48f747737c834f4 Author: Mike Black W9MDB <mdb...@ya...> Date: Wed Mar 29 08:46:05 2023 -0500 Update NEWS diff --git a/NEWS b/NEWS index 562c1a21..73af32a6 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,8 @@ Version 4.6 * Fix FTDX3000 rig split Version 4.5.5 + * Add park to rotorez.c + * Fix rig power on/off from rigctl cmd line and rigctld * Enable async mode by default to prevent WSJT-X crash on IC9700 with transceive on * Fix IC7610 get_powerstat to disable it -- cannot read power status * Fix K3 K22 command error for remote operations @@ -47,7 +49,7 @@ Version 4.5.5 * Add fix for TMD700 * Improve FT-857 get_vfo response when error occurs * Allow FT-857 to use cached vfo on get_vfo when error occurs reading EEPROM - * Fix FTDX10 FT710 set_level AFy + * Fix FTDX10 FT710 set_level AF * Fix FT-450D detection * Fix VFO A/B swapping for gpredict -- hopefully better behavior for VFO swapping rigs Should avoid setting RX freq while TX and avoid TX freq while RX commit ddf11623148650e91c88eee0f29dad116c53d50d Author: Mike Black W9MDB <mdb...@ya...> Date: Tue Mar 28 10:43:07 2023 -0500 Fix auto_power_on from rigctl invocation with --set-conf=auto_power_on=1 https://github.com/Hamlib/Hamlib/issues/1220 diff --git a/src/rig.c b/src/rig.c index e4886f17..efe2811c 100644 --- a/src/rig.c +++ b/src/rig.c @@ -1266,7 +1266,7 @@ int HAMLIB_API rig_open(RIG *rig) powerstat_t powerflag; status = rig_get_powerstat(rig, &powerflag); - if (status == RIG_OK && powerflag == RIG_POWER_OFF) { return (-RIG_EPOWER); } + if (status == RIG_OK && powerflag == RIG_POWER_OFF && rig->state.auto_power_on == 0) { return (-RIG_EPOWER); } // don't need auto_power_on if power is already on if (status == RIG_OK && powerflag == RIG_POWER_ON) { rig->state.auto_power_on = 0; } commit ceb51534c59a1da24c8720ebd3b4e14b5fc20f73 Author: Mike Black W9MDB <mdb...@ya...> Date: Tue Mar 28 10:24:31 2023 -0500 Fix PS0; command in newcat.c https://github.com/Hamlib/Hamlib/issues/1220 diff --git a/rigs/yaesu/newcat.c b/rigs/yaesu/newcat.c index 4250bff4..b1090abb 100644 --- a/rigs/yaesu/newcat.c +++ b/rigs/yaesu/newcat.c @@ -3560,9 +3560,8 @@ int newcat_set_powerstat(RIG *rig, powerstat_t status) case RIG_POWER_OFF: case RIG_POWER_STANDBY: - ps = '0'; - write_block(&state->rigport, (unsigned char *) "PS0;", 4); - break; + retval = write_block(&state->rigport, (unsigned char *) "PS0;", 4); + RETURNFUNC(retval); default: RETURNFUNC(-RIG_ENAVAIL); diff --git a/rigs/yaesu/newcat.h b/rigs/yaesu/newcat.h index 1844e9c9..441914ca 100644 --- a/rigs/yaesu/newcat.h +++ b/rigs/yaesu/newcat.h @@ -50,7 +50,7 @@ typedef char ncboolean; /* shared function version */ -#define NEWCAT_VER "20230228" +#define NEWCAT_VER "20230328" /* Hopefully large enough for future use, 128 chars plus '\0' */ #define NEWCAT_DATA_LEN 129 commit bab6dbe548ac9f6f91c4367a260749ef9cb49873 Author: Mike Black W9MDB <mdb...@ya...> Date: Tue Mar 28 09:43:26 2023 -0500 Fix rigctld get_powerstat https://github.com/Hamlib/Hamlib/issues/1220 diff --git a/rigs/dummy/netrigctl.c b/rigs/dummy/netrigctl.c index ad90419e..1f9ec6fd 100644 --- a/rigs/dummy/netrigctl.c +++ b/rigs/dummy/netrigctl.c @@ -2054,7 +2054,7 @@ static int netrigctl_get_powerstat(RIG *rig, powerstat_t *status) ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); - if (ret == 0) + if (ret > 0) { *status = atoi(buf); } @@ -2736,7 +2736,7 @@ struct rig_caps netrigctl_caps = RIG_MODEL(RIG_MODEL_NETRIGCTL), .model_name = "NET rigctl", .mfg_name = "Hamlib", - .version = "20230117.0", + .version = "20230328.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, commit df70d0f9dac6f9e58c5e4fbfcf25d0268962e2d1 Author: Mike Black W9MDB <mdb...@ya...> Date: Mon Mar 27 10:04:59 2023 -0500 Enable async by default -- this prevents WSJT-X from crashing when transceive mode is on for the IC9700 https://github.com/Hamlib/Hamlib/issues/1264 diff --git a/NEWS b/NEWS index 40fb1a52..562c1a21 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,7 @@ Version 4.6 * Fix FTDX3000 rig split Version 4.5.5 + * Enable async mode by default to prevent WSJT-X crash on IC9700 with transceive on * Fix IC7610 get_powerstat to disable it -- cannot read power status * Fix K3 K22 command error for remote operations * Fix Gemini DX1200 gemini_set_level diff --git a/src/rig.c b/src/rig.c index da0198e2..e4886f17 100644 --- a/src/rig.c +++ b/src/rig.c @@ -552,7 +552,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model) #endif rs->priv = NULL; - rs->async_data_enabled = 0; + rs->async_data_enabled = 1; rs->rigport.fd = -1; rs->pttport.fd = -1; rs->comm_state = 0; commit 6595a2587c4403cfe736d11c0521bd019cafefd5 Author: Mike Black W9MDB <mdb...@ya...> Date: Sat Mar 25 12:38:24 2023 -0500 Update NEWS diff --git a/NEWS b/NEWS index 97d1c51b..40fb1a52 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,7 @@ Version 4.6 * Fix FTDX3000 rig split Version 4.5.5 + * Fix IC7610 get_powerstat to disable it -- cannot read power status * Fix K3 K22 command error for remote operations * Fix Gemini DX1200 gemini_set_level * Fix async I/O to not call flush commit c240bd1cd095a0fc5f2eed66481404cf30435b16 Author: Mike Black W9MDB <mdb...@ya...> Date: Sat Mar 25 11:20:52 2023 -0500 Fix IC-7160 get_powerstat to disable it...cannot read power status from 7610 diff --git a/rigs/icom/ic7610.c b/rigs/icom/ic7610.c index c0322780..742e945b 100644 --- a/rigs/icom/ic7610.c +++ b/rigs/icom/ic7610.c @@ -350,7 +350,7 @@ const struct rig_caps ic7610_caps = RIG_MODEL(RIG_MODEL_IC7610), .model_name = "IC-7610", .mfg_name = "Icom", - .version = BACKEND_VER ".9", + .version = BACKEND_VER ".11", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -582,7 +582,8 @@ const struct rig_caps ic7610_caps = .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, - .get_powerstat = icom_get_powerstat, + // 7610 cannot read power status apparently +// .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, commit ee987bc88e9712ade2bf4353e9bd50bccba50d54 Author: Mike Black W9MDB <mdb...@ya...> Date: Sat Mar 18 23:43:36 2023 -0500 Update NEWS diff --git a/NEWS b/NEWS index dd593da1..97d1c51b 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,7 @@ Version 4.6 * Fix FTDX3000 rig split Version 4.5.5 + * Fix K3 K22 command error for remote operations * Fix Gemini DX1200 gemini_set_level * Fix async I/O to not call flush * Change EX startup commands for Yaesu rigs to allow errors...Win4Yaesu not recognizing EX commands commit 7fa8b6889b1612e992f8d42a3293e63dd2e83f90 Author: Mike Black W9MDB <mdb...@ya...> Date: Sat Mar 18 23:40:45 2023 -0500 For K3 prevent ID; command from K22; command Remote ops was having a problem with K22; https://github.com/Hamlib/Hamlib/issues/1254 diff --git a/rigs/kenwood/kenwood.c b/rigs/kenwood/kenwood.c index 8188c1ac..b3f9398b 100644 --- a/rigs/kenwood/kenwood.c +++ b/rigs/kenwood/kenwood.c @@ -342,9 +342,13 @@ transaction_write: skip |= strncmp(cmdstr, "RU", 2) == 0; skip |= strncmp(cmdstr, "RD", 2) == 0; skip |= strncmp(cmdstr, "KYW", 3) == 0; + skip |= strncmp(cmdstr, "PS1", 3) == 0; + skip |= strncmp(cmdstr, "PS0", 3) == 0; + skip |= strncmp(cmdstr, "K22", 3) == 0; if (skip) { + hl_usleep(200*1000); // give little settle time for these commands goto transaction_quit; } } diff --git a/rigs/kenwood/kenwood.h b/rigs/kenwood/kenwood.h index 66e64f12..1c97ddc5 100644 --- a/rigs/kenwood/kenwood.h +++ b/rigs/kenwood/kenwood.h @@ -29,7 +29,7 @@ #include "misc.h" #include "idx_builtin.h" -#define BACKEND_VER "20230208" +#define BACKEND_VER "20230318" #define EOM_KEN ';' #define EOM_TH '\r' commit e0af8c0a7a4c3a4d1d266705af46ced5f910ae2b Author: Mike Black W9MDB <mdb...@ya...> Date: Sat Mar 18 22:21:07 2023 -0500 Update NEWS diff --git a/NEWS b/NEWS index ac260aa3..dd593da1 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ Version 5.x -- future * Change FT1000MP Mark V model names to align with FT1000MP Version 4.6 + * Add saebrtrack rotor https://sites.google.com/site/marklhammond/saebrtrack * Add offset_vfoa and offset_vfob applying to rig_set_freq * Fix K4 to put it in K40 mode when requesting ID * 2023-11-XX -- Planned for Nov 2023 @@ -30,6 +31,8 @@ Version 4.6 * Fix FTDX3000 rig split Version 4.5.5 + * Fix Gemini DX1200 gemini_set_level + * Fix async I/O to not call flush * Change EX startup commands for Yaesu rigs to allow errors...Win4Yaesu not recognizing EX commands * Fix jst145 set_freq and get_freq * Restore tcflush as some odd behavior was seen that tclush fixes commit 3fa423c63dd19a47bd48cc60eac9b08f4a48caca Author: Mike Black W9MDB <mdb...@ya...> Date: Sat Mar 18 22:18:50 2023 -0500 Fix Gemini DX1200 gemini_set_level function diff --git a/amplifiers/gemini/dx1200.c b/amplifiers/gemini/dx1200.c index ed9786e7..e0a23cc0 100644 --- a/amplifiers/gemini/dx1200.c +++ b/amplifiers/gemini/dx1200.c @@ -61,9 +61,9 @@ const struct amp_caps gemini_amp_caps = AMP_MODEL(AMP_MODEL_GEMINI_DX1200), .model_name = "DX1200/HF-1K", .mfg_name = "Gemini", - .version = "20220710.0", + .version = "20230318.0", .copyright = "LGPL", - .status = RIG_STATUS_ALPHA, + .status = RIG_STATUS_BETA, .amp_type = AMP_TYPE_OTHER, .port_type = RIG_PORT_NETWORK, .write_delay = 0, diff --git a/amplifiers/gemini/gemini.c b/amplifiers/gemini/gemini.c index b105cdcd..7d3f1e4a 100644 --- a/amplifiers/gemini/gemini.c +++ b/amplifiers/gemini/gemini.c @@ -282,13 +282,12 @@ int gemini_set_level(AMP *amp, setting_t level, value_t val) if (val.f < .67) { cmd = "PM\n"; } - return RIG_OK; break; } retval = gemini_transaction(amp, cmd, NULL, 0); - if (retval != RIG_OK) { return retval; } + if (retval == RIG_OK) { return retval; } rig_debug(RIG_DEBUG_ERR, "%s: Unknown level=%s\n", __func__, rig_strlevel(level)); commit 9fc5ec5035921c174061bafcfb610cbf1f73ea46 Author: Mike Black W9MDB <mdb...@ya...> Date: Thu Mar 16 16:41:35 2023 -0500 Fix spelling error in rotctl.c help and add offset settings to rotctl.1 diff --git a/doc/man1/rotctl.1 b/doc/man1/rotctl.1 index a85d8e1a..f947223a 100644 --- a/doc/man1/rotctl.1 +++ b/doc/man1/rotctl.1 @@ -23,6 +23,8 @@ rotctl \- control antenna rotators .OP \-s baud .OP \-t char .OP \-C parm=val +.OP \-o azoffset +.OP \-O eloffset .RB [ \-v [ \-Z ]] .RB [ command | \- ] .YS @@ -131,6 +133,15 @@ The semicolon (\(oq;\(cq) is a common terminator for rotators that accept ASCII character strings. . .TP +.BR \-o ", " \-\-set\-azoffset +Azimuth correction floating point -- during set value is added, during get value is subtracted. +. +.TP +.BR \-O ", " \-\-set\-eloffset +Elevation correction floating point -- during set value is added, during get value is subtracted. +. +. +.TP .BR \-L ", " \-\-show\-conf List all configuration parameters for the rotator defined with .B \-m diff --git a/tests/rotctl.c b/tests/rotctl.c index f8dd99aa..50a1c621 100644 --- a/tests/rotctl.c +++ b/tests/rotctl.c @@ -509,8 +509,8 @@ void usage() " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -t, --send-cmd-term=CHAR set send_cmd command termination char\n" " -C, --set-conf=PARM=VAL set config parameters\n" - " -o, --set-azoffset==VAL set offset for azimuth\n" - " -O, --set-eloffset==VAL set offset for elevation\n" + " -o, --set-azoffset=VAL set offset for azimuth\n" + " -O, --set-eloffset=VAL set offset for elevation\n" " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" commit fe2ebcb06f83991f6c5f3057fb49adef59bf4ad3 Author: Michael Black <mdb...@ya...> Date: Wed Mar 8 15:31:58 2023 -0600 Merge pull request #1244 from mikaelnousiainen/ts2000-fixes Improve Kenwood TS-2000 backend diff --git a/rigs/kenwood/kenwood.c b/rigs/kenwood/kenwood.c index c2b71dc6..8188c1ac 100644 --- a/rigs/kenwood/kenwood.c +++ b/rigs/kenwood/kenwood.c @@ -3133,7 +3133,15 @@ int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) case RIG_LEVEL_AF: { - int vfo_set = vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN ? 0 : 1; + int vfo_num; + if (RIG_IS_TS2000) + { + vfo_num = (vfo == RIG_VFO_C) ? 1 : 0; + } + else + { + vfo_num = (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) ? 0 : 1; + } // some rigs only recognize 0 for vfo_set // https://github.com/Hamlib/Hamlib/issues/304 @@ -3151,7 +3159,7 @@ int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) break; case 3: - SNPRINTF(levelbuf, sizeof(levelbuf), "AG%d%03d", vfo_set, kenwood_val); + SNPRINTF(levelbuf, sizeof(levelbuf), "AG%d%03d", vfo_num, kenwood_val); break; default: @@ -3192,10 +3200,21 @@ int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; - case RIG_LEVEL_SQL: - /* Default to RX#0 */ - SNPRINTF(levelbuf, sizeof(levelbuf), "SQ0%03d", kenwood_val); + case RIG_LEVEL_SQL: { + int vfo_num; + if (RIG_IS_TS2000) + { + vfo_num = (vfo == RIG_VFO_C) ? 1 : 0; + } + else + { + /* Default to RX#0 */ + vfo_num = 0; + } + + SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%d%03d", vfo_num, kenwood_val); break; + } case RIG_LEVEL_AGC: SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", 84 * kenwood_val); @@ -3397,6 +3416,7 @@ int get_kenwood_level(RIG *rig, const char *cmd, float *fval, int *ival) */ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { + char cmdbuf[8]; char lvlbuf[KENWOOD_MAX_BUF_LEN]; char *cmd; int retval; @@ -3423,6 +3443,18 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) cmd = "SM0"; len = 3; } + else if (RIG_IS_TS2000) + { + len = 3; + if (vfo == RIG_VFO_C) + { + cmd = "SM1"; + } + else + { + cmd = "SM0"; + } + } else { cmd = "SM"; @@ -3436,16 +3468,31 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) RETURNFUNC(retval); } - /* XXX atoi ? */ - sscanf(lvlbuf + len, "%d", &val->i); /* rawstr */ + sscanf(lvlbuf + len, "%d", &val->i); break; - case RIG_LEVEL_STRENGTH: + case RIG_LEVEL_STRENGTH: { + int multiplier = 1; + if (RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS480) { cmd = "SM0"; len = 3; } + else if (RIG_IS_TS2000) + { + len = 3; + if (vfo == RIG_VFO_C) + { + cmd = "SM1"; + // TS-2000 sub-transceiver S-meter range is half of the main one + multiplier = 2; + } + else + { + cmd = "SM0"; + } + } else { cmd = "SM"; @@ -3459,7 +3506,8 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) RETURNFUNC(retval); } - sscanf(lvlbuf + len, "%d", &val->i); /* rawstr */ + sscanf(lvlbuf + len, "%d", &val->i); + val->i *= multiplier; if (rig->caps->str_cal.size) { @@ -3469,8 +3517,47 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { val->i = (val->i * 4) - 54; } - break; + } + + case RIG_LEVEL_SQL: { + int ack_len; + int vfo_num; + + if (RIG_IS_TS2000) + { + vfo_num = (vfo == RIG_VFO_C) ? 1 : 0; + } + else + { + /* Default to RX#0 */ + vfo_num = 0; + } + + SNPRINTF(cmdbuf, sizeof(cmdbuf), "SQ%c", vfo_num); + retval = kenwood_transaction(rig, cmdbuf, lvlbuf, sizeof(lvlbuf)); + len = 6; + + if (retval != RIG_OK) + { + return retval; + } + + ack_len = strlen(lvlbuf); + + if (ack_len != len) + { + return -RIG_EPROTO; + } + + if (sscanf(&lvlbuf[len - 3], "%d", &lvl) != 1) + { + return -RIG_EPROTO; + } + + val->f = (float) lvl / 255.f; + return RIG_OK; + } case RIG_LEVEL_ATT: len = RIG_IS_TS890S ? 3 : 6; @@ -3564,8 +3651,8 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) val->f = (power_now - power_min) / (float)(power_max - power_min); RETURNFUNC(RIG_OK); - case RIG_LEVEL_AF: - + case RIG_LEVEL_AF: { + int vfo_num; // first time through we'll determine the AG format // Can be "AG" "AG0" or "AG0/1" // This could be done by rig but easy enough to make it automagic @@ -3622,6 +3709,15 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) RETURNFUNC(RIG_OK); // this is non-fatal for no))w } + if (RIG_IS_TS2000) + { + vfo_num = (vfo == RIG_VFO_C) ? 1 : 0; + } + else + { + vfo_num = (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) ? 0 : 1; + } + switch (priv->ag_format) { case 0: @@ -3630,16 +3726,16 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) break; case 1: - RETURNFUNC(get_kenwood_level(rig, "AG", &val->f, NULL)); + retval = get_kenwood_level(rig, "AG", &val->f, NULL); break; case 2: - RETURNFUNC(get_kenwood_level(rig, "AG0", &val->f, NULL)); + retval = get_kenwood_level(rig, "AG0", &val->f, NULL); break; case 3: - RETURNFUNC(get_kenwood_level(rig, vfo == RIG_VFO_MAIN ? "AG0" : "AG1", &val->f, - NULL)); + SNPRINTF(cmdbuf, sizeof(cmdbuf), "AG%d", vfo_num); + retval = get_kenwood_level(rig, cmdbuf, &val->f,NULL); break; default: @@ -3648,11 +3744,12 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) RETURNFUNC(-RIG_EPROTO); } + RETURNFUNC(retval); + } + case RIG_LEVEL_RF: RETURNFUNC(get_kenwood_level(rig, "RG", &val->f, NULL)); - - case RIG_LEVEL_MICGAIN: { int micgain_now; @@ -4452,7 +4549,7 @@ int kenwood_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) } else { - SNPRINTF(cmd, sizeof(cmd), "CT"); + SNPRINTF(cmd, sizeof(cmd), "CN"); offs = 2; } @@ -4588,6 +4685,7 @@ int kenwood_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, char ackbuf[8]; int offs; int retval; + char antenna; ENTERFUNC; @@ -4612,12 +4710,22 @@ int kenwood_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, RETURNFUNC(retval); } - if (ackbuf[offs] < '1' || ackbuf[offs] > '9') + antenna = ackbuf[offs]; + + if (antenna < '0' || antenna > '9') { RETURNFUNC(-RIG_EPROTO); } - *ant_curr = RIG_ANT_N(ackbuf[offs] - '1'); + if (antenna == '0') + { + // At least TS-2000 return AN0 on VHF/UHF bands + *ant_curr = RIG_ANT_1; + } + else + { + *ant_curr = RIG_ANT_N(ackbuf[offs] - '1'); + } /* XXX check that the returned antenna is valid for the current rig */ @@ -4658,17 +4766,41 @@ int kenwood_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); - switch (ptt) + if (RIG_IS_TS2000) { - case RIG_PTT_ON: ptt_cmd = "TX"; break; - - case RIG_PTT_ON_MIC: ptt_cmd = "TX0"; break; - - case RIG_PTT_ON_DATA: ptt_cmd = "TX1"; break; - - case RIG_PTT_OFF: ptt_cmd = "RX"; break; - - default: RETURNFUNC(-RIG_EINVAL); + switch (ptt) + { + case RIG_PTT_ON: + case RIG_PTT_ON_MIC: + case RIG_PTT_ON_DATA: + ptt_cmd = (vfo == RIG_VFO_C) ? "TX1" : "TX0"; + break; + case RIG_PTT_OFF: + ptt_cmd = "RX"; + break; + default: + RETURNFUNC(-RIG_EINVAL); + } + } + else + { + switch (ptt) + { + case RIG_PTT_ON: + ptt_cmd = "TX"; + break; + case RIG_PTT_ON_MIC: + ptt_cmd = "TX0"; + break; + case RIG_PTT_ON_DATA: + ptt_cmd = "TX1"; + break; + case RIG_PTT_OFF: + ptt_cmd = "RX"; + break; + default: + RETURNFUNC(-RIG_EINVAL); + } } int retval = kenwood_transaction(rig, ptt_cmd, NULL, 0); @@ -4736,8 +4868,8 @@ int kenwood_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) RETURNFUNC(retval); } - if ((RIG_IS_TS990S && RIG_VFO_SUB == vfo) || (RIG_IS_TS2000 - && RIG_VFO_SUB == vfo)) + if ((RIG_IS_TS990S && RIG_VFO_SUB == vfo) || + (RIG_IS_TS2000 && RIG_VFO_C == vfo)) { offs = 3; } diff --git a/rigs/kenwood/ts2000.c b/rigs/kenwood/ts2000.c index 6e70c567..6b0410b4 100644 --- a/rigs/kenwood/ts2000.c +++ b/rigs/kenwood/ts2000.c @@ -1,7 +1,7 @@ /* * Hamlib Kenwood backend - TS2000 description * Copyright (c) 2000-2011 by Stephane Fillod - * + * Copyright (c) 2023 by Mikael Nousiainen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,19 +26,31 @@ #include <hamlib/rig.h> #include "kenwood.h" +#include "token.h" +#include "misc.h" +#include "iofunc.h" +#include "cal.h" -#define TS2000_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) +#define TS2000_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS2000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS2000_AM_TX_MODES RIG_MODE_AM -#define TS2000_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_BC|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_COMP|RIG_FUNC_RIT|RIG_FUNC_XIT) +#define TS2000_LEVEL_GET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_STRENGTH|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ + RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ + RIG_LEVEL_METER|RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) + +#define TS2000_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ + RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ + RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) -#define TS2000_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_COMP|RIG_LEVEL_AGC|RIG_LEVEL_BKINDL|RIG_LEVEL_METER|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) +#define TS2000_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT| \ + RIG_FUNC_TUNER|RIG_FUNC_MON|RIG_FUNC_FBKIN|RIG_FUNC_LOCK|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_ANF) #define TS2000_MAINVFO (RIG_VFO_A|RIG_VFO_B) #define TS2000_SUBVFO (RIG_VFO_C) -#define TS2000_VFO_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN) +#define TS2000_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_CPY|RIG_OP_TUNE) + #define TS2000_SCAN_OP (RIG_SCAN_VFO) #define TS2000_ANTS (RIG_ANT_1|RIG_ANT_2) @@ -54,11 +66,21 @@ {0x1E, 60}}\ } -/* prototypes */ -static int ts2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); -static int ts2000_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, - int read_only); -static int ts2000_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); +#define TS2000_SWR_CAL { 5, \ + { \ + { 0, 1.0f }, \ + { 4, 1.5f }, \ + { 8, 2.0f }, \ + { 12, 3.0f }, \ + { 20, 10.0f } \ + } } + +#define TOK_FUNC_NOISE_REDUCTION_2 TOKEN_BACKEND(102) +#define TOK_LEVEL_DSP_RX_EQUALIZER TOKEN_BACKEND(104) +#define TOK_LEVEL_DSP_TX_EQUALIZER TOKEN_BACKEND(105) +#define TOK_LEVEL_DSP_TX_BANDWIDTH TOKEN_BACKEND(106) +#define TOK_LEVEL_BEEP_VOLUME TOKEN_BACKEND(107) +#define TOK_LEVEL_TX_SIDETONE_VOLUME TOKEN_BACKEND(108) /* * 38 CTCSS sub-audible tones + 1750 tone @@ -72,8 +94,6 @@ tone_t ts2000_ctcss_list[] = 0, }; - - /* * 103 available DCS codes */ @@ -91,9 +111,128 @@ tone_t ts2000_dcs_list[] = 0, }; +int ts2000_ext_tokens[] = +{ + TOK_FUNC_NOISE_REDUCTION_2, TOK_FUNC_FILTER_WIDTH_DATA, + TOK_LEVEL_DSP_RX_EQUALIZER, TOK_LEVEL_DSP_TX_EQUALIZER, TOK_LEVEL_DSP_TX_BANDWIDTH, + TOK_LEVEL_BEEP_VOLUME, TOK_LEVEL_TX_SIDETONE_VOLUME, + TOK_BACKEND_NONE, +}; + +const struct confparams ts2000_ext_funcs[] = +{ + { + TOK_FUNC_NOISE_REDUCTION_2, "NR2", "Noise reduction 2", "Noise reduction 2", + NULL, RIG_CONF_CHECKBUTTON, + }, + { RIG_CONF_END, NULL, } +}; + +const struct confparams ts2000_ext_levels[] = +{ + { + TOK_LEVEL_DSP_RX_EQUALIZER, "DSP_RX_EQUALIZER", "DSP RX equalizer", "DSP RX equalizer type", + NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "H BOOST", "F PASS", "B BOOST", "CONV-EN", "USER", NULL } } } + }, + { + TOK_LEVEL_DSP_TX_EQUALIZER, "DSP_TX_EQUALIZER", "DSP TX equalizer", "DSP TX equalizer type", + NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "H BOOST", "F PASS", "B BOOST", "CONV-EN", "USER", NULL } } } + }, + { + TOK_LEVEL_DSP_TX_BANDWIDTH, "DSP_TX_BANDWIDTH", "DSP TX bandwidth", "DSP TX bandwidth for SSB and AM", + NULL, RIG_CONF_COMBO, { .c = { .combostr = { "2.0 kHz", "2.2 kHz", "2.4 kHz", "2.6 kHz", "2.8 kHz", "3.0 kHz", NULL } } } + }, + { + TOK_LEVEL_BEEP_VOLUME, "BEEP_VOLUME", "Beep volume", "Beep volume", + NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } + }, + { + TOK_LEVEL_TX_SIDETONE_VOLUME, "TX_SIDETONE_VOLUME", "TX sidetone volume", "TX sidetone volume", + NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } + }, + { RIG_CONF_END, NULL, } +}; + +static struct kenwood_filter_width ts2000_filter_width[] = +{ + { RIG_MODE_CW | RIG_MODE_CWR, 50, 50 }, + { RIG_MODE_CW | RIG_MODE_CWR, 80, 80 }, + { RIG_MODE_CW | RIG_MODE_CWR, 100, 100 }, + { RIG_MODE_CW | RIG_MODE_CWR, 150, 150 }, + { RIG_MODE_CW | RIG_MODE_CWR, 200, 200 }, + { RIG_MODE_CW | RIG_MODE_CWR, 300, 300 }, + { RIG_MODE_CW | RIG_MODE_CWR, 400, 400 }, + { RIG_MODE_CW | RIG_MODE_CWR, 500, 500 }, + { RIG_MODE_CW | RIG_MODE_CWR, 600, 600 }, + { RIG_MODE_CW | RIG_MODE_CWR, 1000, 1000 }, + { RIG_MODE_CW | RIG_MODE_CWR, 2000, 2000 }, + { RIG_MODE_RTTY | RIG_MODE_RTTYR, 250, 250 }, + { RIG_MODE_RTTY | RIG_MODE_RTTYR, 500, 500 }, + { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1000, 1000 }, + { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1500, 1500 }, + { RIG_MODE_SSB, 0, 2400 }, + { RIG_MODE_SSB, 1, 500 }, // NAR1 optional filter + { RIG_MODE_SSB, 2, 270 }, // NAR2 optional filter + { RIG_MODE_FM, 0, 6000 }, + { RIG_MODE_FM, 1, 12000 }, + { RIG_MODE_AM, 0, 2400 }, + { RIG_MODE_AM, 1, 6000 }, // NAR1 optional filter (?) + { RIG_MODE_NONE, -1, -1 }, +}; + +static struct kenwood_slope_filter ts2000_slope_filter_high[] = +{ + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 1400 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 1600 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 1800 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 2000 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 2200 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 2400 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 2600 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 2800 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 3000 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 3400 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 4000 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 5000 }, + { RIG_MODE_AM, 0, 0, 2500 }, + { RIG_MODE_AM, 0, 1, 3000 }, + { RIG_MODE_AM, 0, 2, 4000 }, + { RIG_MODE_AM, 0, 3, 5000 }, + { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 0, 170 }, + { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 1, 1930 }, + { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 2, 2160 }, + { RIG_MODE_NONE, 0, -1, -1 }, +}; + +static struct kenwood_slope_filter ts2000_slope_filter_low[] = +{ + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 0 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 50 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 100 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 200 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 300 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 400 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 500 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 600 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 700 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 800 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 900 }, + { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 10, 1, 1000 }, + { RIG_MODE_AM, 0, 0, 0 }, + { RIG_MODE_AM, 0, 1, 100 }, + { RIG_MODE_AM, 0, 2, 200 }, + { RIG_MODE_AM, 0, 3, 500 }, + { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 0, 2500 }, + { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 1, 1000 }, + { RIG_MODE_NONE, 0, -1, -1 }, +}; + static struct kenwood_priv_caps ts2000_priv_caps = { .cmdtrm = EOM_KEN, + .filter_width = ts2000_filter_width, + .slope_filter_high = ts2000_slope_filter_high, + .slope_filter_low = ts2000_slope_filter_low, }; /* memory capabilities */ @@ -118,1059 +257,1650 @@ static struct kenwood_priv_caps ts2000_priv_caps = /* - * ts2000 rig capabilities. - * - * part of infos comes from http://www.kenwood.net/ + * Function definitions below */ -const struct rig_caps ts2000_caps = + +int ts2000_init(RIG *rig) { - RIG_MODEL(RIG_MODEL_TS2000), - .model_name = "TS-2000", - .mfg_name = "Kenwood", - .version = BACKEND_VER ".0", - .copyright = "LGPL", - .status = RIG_STATUS_STABLE, - .rig_type = RIG_TYPE_TRANSCEIVER, - .ptt_type = RIG_PTT_RIG, - .dcd_type = RIG_DCD_RIG, - .port_type = RIG_PORT_SERIAL, - .serial_rate_min = 1200, - .serial_rate_max = 57600, - .serial_data_bits = 8, - .serial_stop_bits = 1, - .serial_parity = RIG_PARITY_NONE, - .serial_handshake = RIG_HANDSHAKE_NONE, - .write_delay = 0, - .post_write_delay = 0, /* ms */ - .timeout = 200, - .retry = 10, + struct kenwood_priv_data *priv; + int retval; - .has_get_func = TS2000_FUNC_ALL, - .has_set_func = TS2000_FUNC_ALL, - .has_get_level = TS2000_LEVEL_ALL, - .has_set_level = RIG_LEVEL_SET(TS2000_LEVEL_ALL), - .has_get_parm = RIG_PARM_NONE, - .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ - .level_gran = + ENTERFUNC; + + retval = kenwood_init(rig); + + if (retval != RIG_OK) { -#include "level_gran_kenwood.h" - }, - .parm_gran = {}, - .vfo_ops = TS2000_VFO_OP, - .scan_ops = TS2000_SCAN_OP, - .ctcss_list = ts2000_ctcss_list, - .dcs_list = ts2000_dcs_list, - .preamp = { 20, RIG_DBLST_END, }, /* FIXME: real preamp? */ - .attenuator = { 20, RIG_DBLST_END, }, - .max_rit = kHz(20), - .max_xit = kHz(20), - .max_ifshift = kHz(1), - .targetable_vfo = RIG_TARGETABLE_FREQ, - .transceive = RIG_TRN_RIG, - .agc_level_count = 5, - .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_ON }, - .bank_qty = 0, - .chan_desc_sz = 7, + return retval; + } - .chan_list = { - { 0, 299, RIG_MTYPE_MEM, TS2000_MEM_CAP }, - RIG_CHAN_END, - }, + priv = (struct kenwood_priv_data *) rig->state.priv; - .rx_range_list1 = { - {kHz(300), MHz(60), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO, TS2000_ANTS}, - {MHz(144), MHz(146), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, - {MHz(430), MHz(440), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, - {MHz(144), MHz(146), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, - {MHz(430), MHz(440), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, - RIG_FRNG_END, - }, /* rx range */ - .tx_range_list1 = { - {kHz(1830), kHz(1850), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(1830), kHz(1850), TS2000_AM_TX_MODES, 2000, 25000, TS2000_MAINVFO, TS2000_ANTS}, - {kHz(3500), kHz(3800), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(3500), kHz(3800), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(7), kHz(7100), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(7), kHz(7100), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(10.1), MHz(10.15), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(10.1), MHz(10.15), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(14), kHz(14350), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(14), kHz(14350), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(18068), kHz(18168), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(18068), kHz(18168), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(21), kHz(21450), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(21), kHz(21450), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(24890), kHz(24990), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(24890), kHz(24990), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(28), kHz(29700), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(28), kHz(29700), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(50), MHz(50.2), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(50), MHz(50.2), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(144), MHz(146), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO}, - {MHz(144), MHz(146), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO}, - {MHz(430), MHz(440), TS2000_OTHER_TX_MODES, W(5), W(50), TS2000_MAINVFO}, - {MHz(430), MHz(440), TS2000_AM_TX_MODES, W(5), W(12.5), TS2000_MAINVFO}, - RIG_FRNG_END, - }, /* tx range */ + priv->ag_format = 3; + priv->micgain_min = 0; + priv->micgain_max = 100; - .rx_range_list2 = { - {kHz(300), MHz(60), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO, TS2000_ANTS}, - {MHz(142), MHz(152), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, - {MHz(420), MHz(450), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, - {MHz(118), MHz(174), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, - {MHz(220), MHz(512), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, - RIG_FRNG_END, - }, /* rx range */ - .tx_range_list2 = { - {kHz(1800), MHz(2), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(1800), MHz(2), TS2000_AM_TX_MODES, 2000, 25000, TS2000_MAINVFO, TS2000_ANTS}, - {kHz(3500), MHz(4), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(3500), MHz(4), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(7), kHz(7300), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(7), kHz(7300), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(10.1), MHz(10.15), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(10.1), MHz(10.15), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(14), kHz(14350), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(14), kHz(14350), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(18068), kHz(18168), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(18068), kHz(18168), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(21), kHz(21450), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(21), kHz(21450), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(24890), kHz(24990), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {kHz(24890), kHz(24990), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(28), kHz(29700), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(28), kHz(29700), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(50), MHz(54), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(50), MHz(54), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, - {MHz(144), MHz(148), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO}, - {MHz(144), MHz(148), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO}, - {MHz(430), MHz(450), TS2000_OTHER_TX_MODES, W(5), W(50), TS2000_MAINVFO}, - {MHz(430), MHz(450), TS2000_AM_TX_MODES, W(5), W(12.5), TS2000_MAINVFO}, - RIG_FRNG_END, - }, /* tx range */ - .tuning_steps = { - {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, 1}, - {TS2000_ALL_MODES, 10}, - {TS2000_ALL_MODES, 100}, - {TS2000_ALL_MODES, kHz(1)}, - {TS2000_ALL_MODES, kHz(2.5)}, - {TS2000_ALL_MODES, kHz(5)}, - {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, - {TS2000_ALL_MODES, kHz(10)}, - {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, - {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, - {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, - {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, - {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, - {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, - {RIG_MODE_AM | RIG_MODE_FM, kHz(50)}, - {RIG_MODE_AM | RIG_MODE_FM, kHz(100)}, - {TS2000_ALL_MODES, MHz(1)}, - {TS2000_ALL_MODES, 0}, /* any tuning step */ - RIG_TS_END, - }, + RETURNFUNC(RIG_OK); +} - /* mode/filter list, remember: order matters! */ - .filters = { - {RIG_MODE_SSB, kHz(2.2)}, - {RIG_MODE_CW, Hz(600)}, - {RIG_MODE_RTTY, Hz(1500)}, - {RIG_MODE_AM, kHz(6)}, - {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, - RIG_FLT_END, - }, +static int ts2000_set_ex_menu(RIG *rig, int number, int value_len, int value) +{ + char buf[20]; - .str_cal = TS2000_STR_CAL, + ENTERFUNC; - .priv = (void *)& ts2000_priv_caps, + SNPRINTF(buf, sizeof(buf), "EX%03d0000%0*d", number, value_len, value); - .rig_init = kenwood_init, - .rig_open = kenwood_open, - .rig_close = kenwood_close, - .rig_cleanup = kenwood_cleanup, - .set_freq = kenwood_set_freq, - .get_freq = kenwood_get_freq, - .set_rit = kenwood_set_rit, - .get_rit = kenwood_get_rit, - .set_xit = kenwood_set_xit, - .get_xit = kenwood_get_xit, - .set_mode = kenwood_set_mode, - .get_mode = kenwood_get_mode, - .set_vfo = kenwood_set_vfo, - .get_vfo = kenwood_get_vfo_if, - .set_split_vfo = kenwood_set_split_vfo, - .get_split_vfo = kenwood_get_split_vfo_if, - .set_ctcss_tone = kenwood_set_ctcss_tone_tn, - .get_ctcss_tone = kenwood_get_ctcss_tone, - .set_ctcss_sql = kenwood_set_ctcss_sql, - .get_ctcss_sql = kenwood_get_ctcss_sql, - .get_ptt = kenwood_get_ptt, - .set_ptt = kenwood_set_ptt, - .get_dcd = kenwood_get_dcd, - .set_func = kenwood_set_func, - .get_func = kenwood_get_func, - .set_level = kenwood_set_level, - .get_level = ts2000_get_level, - .set_ant = kenwood_set_ant, - .get_ant = kenwood_get_ant, - .send_morse = kenwood_send_morse, - .wait_morse = rig_wait_morse, - .vfo_op = kenwood_vfo_op, - .scan = kenwood_scan, - .set_mem = kenwood_set_mem, - .get_mem = kenwood_get_mem, - .get_channel = ts2000_get_channel, - .set_channel = ts2000_set_channel, - .set_trn = kenwood_set_trn, - .get_trn = kenwood_get_trn, - .set_powerstat = kenwood_set_powerstat, - .get_powerstat = kenwood_get_powerstat, - .get_info = kenwood_get_info, - .reset = kenwood_reset, + RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); +} - .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS -}; +static int ts2000_get_ex_menu(RIG *rig, int number, int value_len, int *value) +{ + int retval; + char buf[20]; + char ackbuf[20]; -/* - * Function definitions below - */ + rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); -/* - * ts2000_get_channel - * Read command format: - M|R|P1|P2|P3|P3|;| - * P1: 0 - RX frequency, 1 - TX frequency - Memory channel 290 ~ 299: P1=0 (start frequency), P1=1 (end frequency) - P2 - bank number - allowed values: <space>, 0, 1 or 2 - P3 - channel number 00-99 + SNPRINTF(buf, sizeof(buf), "EX%03d0000", number); - Returned value: - M | R |P1 |P2 |P3 |P3 |P4 |P4 |P4 |P4 | - P4 |P4 |P4 |P4 |P4 |P4 |P4 |P5 |P6 |P7 | - P8 |P8 |P9 |P9 |P10|P10|P10|P11|P12|P13| - P13|P13|P13|P13|P13|P13|P13|P13|P14|P14| - P15|P16|P16|P16|P16|P16|P16|P16|P16| ; | - P1 - P3 described above - P4: Frequency in Hz (11-digit). - P5: Mode. 1: LSB, 2: USB, 3: CW, 4: FM, 5: AM, 6: FSK, 7: CR-R, 8: Reserved, 9: FSK-R - P6: Lockout status. 0: Lockout OFF, 1: Lockout ON. - P7: 0: OFF, 1: TONE, 2: CTCSS, 3: DCS. - P8: Tone Number. Allowed values 01 (67Hz) - 38 (250.3Hz) - P9: CTCSS tone number. Allowed values 01 (67Hz) - 38 (250.3Hz) - P10: DCS code. Allowed values 000 (023 DCS code) to 103 (754 DCS code). - P11: REVERSE status. - P12: SHIFT status. 0: Simplex, 1: +, 2: –, 3: = (All E-types) - P13: Offset frequency in Hz (9-digit). - Allowed values 000000000 - 059950000 in steps of 50000. Unused digits must be 0. - P14: Step size. Allowed values: - for SSB, CW, FSK mode: 00 - 03 - 00: 1 kHz, 01: 2.5 kHz, 02: 5 kHz, 03: 10 kHz - for AM, FM mode: 00 - 09 - 00: 5 kHz, 01: 6.25 kHz, 02: 10 kHz, 03: 12.5 kHz, 04: 15 kHz, - 05: 20 kHz, 06: 25 kHz, 07: 30 kHz, 08: 50 kHz, 09: 100 kHz - P15: Memory Group number (0 ~ 9). - P16: Memory name. A maximum of 8 characters. - - */ - -int ts2000_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) -{ - int err; - int tmp; - size_t length; - char buf[52]; - char cmd[8]; - struct kenwood_priv_caps *caps = kenwood_caps(rig); - - rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + retval = kenwood_safe_transaction(rig, buf, ackbuf, sizeof(ackbuf), + 9 + value_len); - if (!chan || chan->vfo != RIG_VFO_MEM) + if (retval != RIG_OK) { - return -RIG_EINVAL; + RETURNFUNC2(retval); } - /* put channel num in the command string */ - SNPRINTF(cmd, sizeof(cmd), "MR0%03d;", chan->channel_num); + sscanf(ackbuf + 9, "%d", value); - err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); + RETURNFUNC2(RIG_OK); +} - if (err != RIG_OK) - { - return err; - } +static int ts2000_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) +{ + char buf[20]; - length = strlen(buf); - memset(chan, 0x00, sizeof(channel_t)); + rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); - chan->vfo = RIG_VFO_MEM; + switch (func) + { + case RIG_FUNC_MON: + SNPRINTF(buf, sizeof(buf), "ML00%c", (status == 0) ? '0' : '1'); + RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); - /* parse from right to left */ + case RIG_FUNC_LOCK: + SNPRINTF(buf, sizeof(buf), "LK%c%c", (status == 0) ? '0' : '1', + (status == 0) ? '0' : '1'); + RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); - /* XXX based on the available documentation, there is no command - * to read out the filters of a given memory channel. The rig, however, - * stores this information. - */ - /* First check if a name is assigned. - Name is returned at positions 41-48 (counting from 0) */ - if (length > 41) - { -// rig_debug(RIG_DEBUG_VERBOSE, "Copying channel description: %s\n", &buf[ 41 ] ); - strcpy(chan->channel_desc, &buf[ 41 ]); + default: + return kenwood_set_func(rig, vfo, func, status); } +} - /* Memory group no */ - chan->scan_group = buf[ 40 ] - '0'; - /* Fields 38-39 contain tuning step as a number 00 - 09. - Tuning step depends on this number and the mode, - just save it for now */ - buf[ 40 ] = '\0'; - tmp = atoi(&buf[ 38]); - /* Offset frequency */ - buf[ 38 ] = '\0'; - chan->rptr_offs = atoi(&buf[ 29 ]); +static int ts2000_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) +{ + char buf[20]; + int retval; - /* Shift type - WARNING: '=' shift type not programmed */ - if (buf[ 28 ] == '1') + ENTERFUNC; + + switch (func) { - chan->rptr_shift = RIG_RPT_SHIFT_PLUS; - } - else + case RIG_FUNC_MON: { - if (buf[ 28 ] == '2') - { - chan->rptr_shift = RIG_RPT_SHIFT_MINUS; - } - else + int raw_value; + retval = kenwood_safe_transaction(rig, "ML", buf, sizeof(buf), 5); + + if (retval != RIG_OK) { - chan->rptr_shift = RIG_RPT_SHIFT_NONE; + RETURNFUNC(retval); } - } - /* Reverse status */ - if (buf[27] == '1') - { - chan->funcs |= RIG_FUNC_REV; - } + sscanf(buf, "ML%d", &raw_value); - /* Check for tone, CTCSS and DCS */ - /* DCS code first */ - if (buf[ 19 ] == '3') - { - if (rig->caps->dcs_list) - { - buf[ 27 ] = '\0'; - chan->dcs_code = rig->caps->dcs_list[ atoi(&buf[ 24 ]) ]; - chan->dcs_sql = chan->dcs_code; - chan->ctcss_tone = 0; - chan->ctcss_sql = 0; - } + *status = (raw_value > 0); + break; } - else - { - chan->dcs_code = 0; - chan->dcs_sql = 0; - /* CTCSS code - Caution, CTCSS codes, unlike DCS codes, are numbered from 1! */ - buf[ 24 ] = '\0'; - if (buf[ 19 ] == '2') - { - chan->funcs |= RIG_FUNC_TSQL; + case RIG_FUNC_LOCK: + retval = kenwood_safe_transaction(rig, "LK", buf, sizeof(buf), 4); - if (rig->caps->ctcss_list) - { - chan->ctcss_sql = rig->caps->ctcss_list[ atoi(&buf[22]) - 1 ]; - chan->ctcss_tone = 0; - } - } - else + if (retval != RIG_OK) { - chan->ctcss_sql = 0; + RETURNFUNC(retval); + } - /* CTCSS tone */ - if (buf[ 19 ] == '1') - { - chan->funcs |= RIG_FUNC_TONE; - buf[ 22 ] = '\0'; + *status = buf[2] != '0' || buf[3] != '0'; + break; - if (rig->caps->ctcss_list) - { - chan->ctcss_tone = rig->caps->ctcss_list[ atoi(&buf[20]) - 1 ]; - } - } - else - { - chan->ctcss_tone = 0; - } - } + default: + return kenwood_get_func(rig, vfo, func, status); } + RETURNFUNC(RIG_OK); +} + +/* + * WARNING: The commands differ slightly from the general versions in kenwood.c + * e.g.: "SQ"=>"SQ0" , "AG"=>"AG0" + */ +static int ts2000_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +{ + char levelbuf[16]; + int kenwood_val; + char vfo_num = (vfo == RIG_VFO_C) ? '1' : '0'; + + rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); - /* memory lockout */ - if (buf[18] == '1') + switch (level) { - chan->flags |= RIG_CHFLAG_SKIP; - } + case RIG_LEVEL_RF: + kenwood_val = val.f * 255; + SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); + break; - /* mode */ - chan->mode = kenwood2rmode(buf[17] - '0', caps->mode_table); + case RIG_LEVEL_AF: + return kenwood_set_level(rig, vfo, level, val); - /* Now we have the mode, let's finish the tuning step */ - if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) - { - switch (tmp) + case RIG_LEVEL_SQL: + kenwood_val = val.f * 255; + SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%c%03d", vfo_num, kenwood_val); + break; + + case RIG_LEVEL_AGC: + /* Possible values for TS-2000 are 0(=off)-020(=slow) */ + + switch (val.i) { - case 0: chan->tuning_step = kHz(5); break; + case RIG_AGC_OFF: + kenwood_val = 0; + break; - case 1: chan->tuning_step = kHz(6.25); break; + case RIG_AGC_SUPERFAST: + kenwood_val = 1; + break; - case 2: chan->tuning_step = kHz(10); break; + case RIG_AGC_FAST: + kenwood_val = 5; + break; - case 3: chan->tuning_step = kHz(12.5); break; + case RIG_AGC_MEDIUM: + kenwood_val = 10; + break; - case 4: chan->tuning_step = kHz(15); break; + case RIG_AGC_SLOW: + kenwood_val = 20; + break; - case 5: chan->tuning_step = kHz(20); break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: unsupported agc value", __func__); + return -RIG_EINVAL; + } - case 6: chan->tuning_step = kHz(25); break; + SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", kenwood_val); + break; - case 7: chan->tuning_step = kHz(30); break; + case RIG_LEVEL_MONITOR_GAIN: + kenwood_val = val.f * 9.0; + SNPRINTF(levelbuf, sizeof(levelbuf), "ML%03d", kenwood_val); + break; - case 8: chan->tuning_step = kHz(50); break; + case RIG_LEVEL_NB: + kenwood_val = val.f * 10.0; + SNPRINTF(levelbuf, sizeof(levelbuf), "NL%03d", kenwood_val); + break; - case 9: chan->tuning_step = kHz(100); break; + case RIG_LEVEL_NR: + kenwood_val = val.f * 9.0; + SNPRINTF(levelbuf, sizeof(levelbuf), "RL%02d", kenwood_val); + break; - default: chan->tuning_step = 0; + case RIG_LEVEL_PREAMP: + if (val.i != 12 && val.i != 0) + { + RETURNFUNC(-RIG_EINVAL); } - } - else - { - switch (tmp) + + SNPRINTF(levelbuf, sizeof(levelbuf), "PA%c", (val.i == 12) ? '1' : '0'); + break; + + case RIG_LEVEL_ATT: + if (val.i != 12 && val.i != 0) { - case 0: chan->tuning_step = kHz(1); break; + RETURNFUNC(-RIG_EINVAL); + } - case 1: chan->tuning_step = kHz(2.5); break; + SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", (val.i == 12) ? 1 : 0); + break; - case 2: chan->tuning_step = kHz(5); break; + case RIG_LEVEL_METER: + switch (val.i) + { + case RIG_METER_SWR: + kenwood_val = 1; + break; - case 3: chan->tuning_step = kHz(10); break; + case RIG_METER_COMP: + kenwood_val = 2; + break; - default: chan->tuning_step = 0; + case RIG_METER_ALC: + kenwood_val = 3; + break; + + default: + RETURNFUNC(-RIG_EINVAL); } - } - /* Frequency */ - buf[17] = '\0'; - chan->freq = atoi(&buf[6]); + SNPRINTF(levelbuf, sizeof(levelbuf), "RM%d", kenwood_val); + break; - if (chan->freq == RIG_FREQ_NONE) - { - return -RIG_ENAVAIL; + case RIG_LEVEL_CWPITCH: + if (val.i > 1000 || val.i < 400) + { + RETURNFUNC(-RIG_EINVAL); + } + + RETURNFUNC(ts2000_set_ex_menu(rig, 31, 2, (val.i - 400) / 50)); + + default: + return kenwood_set_level(rig, vfo, level, val); } - buf[6] = '\0'; - chan->channel_num = atoi(&buf[3]); + return kenwood_transaction(rig, levelbuf, NULL, 0); +} +// TS-2000 can only read one meter at a time and the user must select +// the meter using RIG_LEVEL_METER. This function returns the meter value if +// the selected meter matches the expected meter. +static int ts2000_read_meter(RIG *rig, int expected_meter, int *value) +{ + int retval; + char cmdbuf[8]; + struct rig_state *rs = &rig->state; + char ackbuf[32]; + int expected_len = 8; + int read_meter; + int read_value; - /* Check split freq */ - cmd[2] = '1'; - err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); + ENTERFUNC; - if (err != RIG_OK) + SNPRINTF(cmdbuf, sizeof(cmdbuf), "RM;"); + + retval = write_block(&rs->rigport, (unsigned char *) cmdbuf, strlen(cmdbuf)); + + rig_debug(RIG_DEBUG_TRACE, "%s: write_block retval=%d\n", __func__, retval); + + if (retval != RIG_OK) { - return err; + RETURNFUNC(retval); } - chan->tx_mode = kenwood2rmode(buf[17] - '0', caps->mode_table); + // TS-2000 returns values for a single meter at the same ti... [truncated message content] |