From 755d719505971b12fbdce6ba6f821dc636dc3251 Mon Sep 17 00:00:00 2001 From: Michael Black W9MDB Date: Thu, 1 Oct 2020 16:08:53 -0700 Subject: [PATCH] Fix K3/K3S/KX2/KX3 RFPOWER set/get for band specific power levels (cherry picked from commit 3f94e66c9fe8ec3db7fe6494e58592334e913c27) --- rigs/kenwood/elecraft.c | 35 ++++++++++++++++++++++--- rigs/kenwood/k3.c | 58 ++++++++++++++++++++++++++++++++++++++--- rigs/kenwood/kenwood.h | 14 +++++----- 3 files changed, 94 insertions(+), 13 deletions(-) diff --git a/rigs/kenwood/elecraft.c b/rigs/kenwood/elecraft.c index 52e4d2491..97bc1381b 100644 --- a/rigs/kenwood/elecraft.c +++ b/rigs/kenwood/elecraft.c @@ -94,8 +94,9 @@ int elecraft_get_firmware_revision_level(RIG *rig, const char *cmd, int elecraft_open(RIG *rig) { int err; - char id[KENWOOD_MAX_BUF_LEN]; + char buf[KENWOOD_MAX_BUF_LEN]; struct kenwood_priv_data *priv = rig->state.priv; + char *model = "Unknown"; rig_debug(RIG_DEBUG_VERBOSE, "%s called, rig version=%s\n", __func__, @@ -134,7 +135,7 @@ int elecraft_open(RIG *rig) return err; } - err = read_string(&rs->rigport, id, sizeof(id), ";", 1); + err = read_string(&rs->rigport, buf, sizeof(buf), ";", 1); if (err < 0) { @@ -142,7 +143,7 @@ int elecraft_open(RIG *rig) return err; } - rig_debug(RIG_DEBUG_VERBOSE, "%s: id=%s\n", __func__, id); + rig_debug(RIG_DEBUG_VERBOSE, "%s: id=%s\n", __func__, buf); #if 0 if (err != RIG_OK) @@ -155,7 +156,7 @@ int elecraft_open(RIG *rig) } else // Standard Kenwood { - err = verify_kenwood_id(rig, id); + err = verify_kenwood_id(rig, buf); if (err != RIG_OK) { @@ -182,6 +183,32 @@ int elecraft_open(RIG *rig) case RIG_MODEL_K3S: case RIG_MODEL_KX2: case RIG_MODEL_KX3: + // we need to know what's hooked up for PC command max levels + err = kenwood_safe_transaction(rig, "OM", buf, KENWOOD_MAX_BUF_LEN, 15); + if (err != RIG_OK) { return err; } + rig_debug(RIG_DEBUG_TRACE, "%s: OM=%s\n", __func__, buf); + priv->has_kpa3 = 0; + if (strstr(buf,"P")) priv->has_kpa3 = 1; + if (buf[13] == '0') // then we have a KX3 or KX2 + { + char modelnum; + modelnum = buf[14]; + switch (modelnum) + { + case '1': model = "KX2";break; + case '2': model = "KX3";break; + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unknown Elecraft modelnum=%c, expected 1 or 2\n", __func__, modelnum); + break; + } + if (strstr(buf,"P")) priv->has_kpa100 = 1; + } + else { + model = "K3"; + if (strstr(buf,"R")) model = "K3S"; + } + rig_debug(RIG_DEBUG_TRACE, "%s: model=%s, kpa3%d\n", __func__, model, priv->has_kpa3); + err = elecraft_get_extension_level(rig, "K2", &priv->k2_ext_lvl); if (err != RIG_OK) diff --git a/rigs/kenwood/k3.c b/rigs/kenwood/k3.c index c1846d3ef..c33357cba 100644 --- a/rigs/kenwood/k3.c +++ b/rigs/kenwood/k3.c @@ -1579,6 +1579,48 @@ int k3_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, return RIG_OK; } +static int k3_get_maxpower(RIG *rig) +{ + int retval; + int maxpower = 12; // K3 default power level + char levelbuf[16]; + struct kenwood_priv_data *priv = rig->state.priv; + // default range is 0-12 if there is no KPA3 installed + if (priv->has_kpa3 || priv->has_kpa100) maxpower = 110; + if (RIG_IS_KX2 || RIG_IS_KX3) { + + int bandnum = -1; + retval = kenwood_safe_transaction(rig, "BN", levelbuf, KENWOOD_MAX_BUF_LEN, 4); + if (retval != RIG_OK) { return retval; } + sscanf(levelbuf,"BN%d", &bandnum); + switch(bandnum) + { + case 1: + case 2: + case 3: + case 4: + case 5: + maxpower = 15; + break; + case 0: // 160M + case 6: // 17M + case 7: // 15M + case 8: // 12M + case 9: // 10M + maxpower = 12; + break; + case 10: // 6M + maxpower = 10; + break; + default: // are transverters all limited to 3W?? + maxpower = 3; + break; + } + } + rig_debug(RIG_DEBUG_TRACE, "%s: maxpower=%d\n", __func__, maxpower); + return maxpower; +} + int k3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; @@ -1682,9 +1724,8 @@ int k3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) break; case RIG_LEVEL_RFPOWER: - // range is 0-12 if there is no KPA3 installed - snprintf(levelbuf, sizeof(levelbuf), "PC%03d", (int)(val.f * 12.0f)); - break; + snprintf(levelbuf, sizeof(levelbuf), "PC%03d", (int)(val.f * k3_get_maxpower(rig))); + break; default: return kenwood_set_level(rig, vfo, level, val); @@ -1957,6 +1998,17 @@ int k3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 60.0f; break; + case RIG_LEVEL_RFPOWER: + retval = kenwood_safe_transaction(rig, "PC", levelbuf, sizeof(levelbuf), 5); + + if (retval != RIG_OK) + { + return retval; + } + + sscanf(levelbuf + 2, "%d", &lvl); + val->f = (float) lvl / k3_get_maxpower(rig); + break; default: return kenwood_get_level(rig, vfo, level, val); diff --git a/rigs/kenwood/kenwood.h b/rigs/kenwood/kenwood.h index 85ea65893..ce8ec5b25 100644 --- a/rigs/kenwood/kenwood.h +++ b/rigs/kenwood/kenwood.h @@ -117,18 +117,20 @@ struct kenwood_priv_data int k2_ext_lvl; /* Initial K2 extension level */ int k3_ext_lvl; /* Initial K3 extension level */ int k2_md_rtty; /* K2 RTTY mode available flag, 1 = RTTY, 0 = N/A */ - char *fw_rev; /* firmware revision level */ - int trn_state; /* AI state discovered at startup */ + int has_kpa3; /* Elecraft K3 has k3pa for PC command */ + int has_kpa100; /* Elecraft KX3/KX2 has kpa100 for PC command */ + char *fw_rev; /* firmware revision level */ + int trn_state; /* AI state discovered at startup */ unsigned fw_rev_uint; /* firmware revision as a number 1.07 -> 107 */ char verify_cmd[4]; /* command used to verify set commands */ int is_emulation; /* flag for TS-2000 emulations */ void *data; /* model specific data */ - rmode_t curr_mode; /* used for is_emulation to avoid get_mode on VFOB */ + rmode_t curr_mode; /* used for is_emulation to avoid get_mode on VFOB */ struct timespec cache_start; char last_if_response[KENWOOD_MAX_BUF_LEN]; - int poweron; /* to avoid powering on more than once */ - int has_rit2; /* rig has set 2 rit command */ - int ag_format; /* which AG command is being used...see LEVEL_AF in kenwood.c*/ + int poweron; /* to avoid powering on more than once */ + int has_rit2; /* rig has set 2 rit command */ + int ag_format; /* which AG command is being used...see LEVEL_AF in kenwood.c*/ };