Implemented dynamic detection of RFPOWER levels for Kenwoods

Need to remove RFPOWER customizations from other Kenwood backends now
Need to do this same thing for MICGAIN
https://github.com/Hamlib/Hamlib/issues/389
pull/412/head
Michael Black W9MDB 2020-10-03 00:16:02 -05:00
rodzic 86949c4ef7
commit 5ae848c48f
3 zmienionych plików z 80 dodań i 38 usunięć

Wyświetl plik

@ -2179,6 +2179,63 @@ int kenwood_get_mode_if(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
return RIG_OK;
}
/* kenwood_get_power_minmax
* Kenwood rigs have different power levels by mode and by rig
* This routine relies on the idea that setting the power
* to 0 and 255 will result in the minimum and maximum values being set
* If a rig doesn't behave this way then customize inside that rig's backend
*/
static int kenwood_get_power_minmax(RIG *rig, int *power_now, int *power_min,
int *power_max,
int restore)
{
int retval;
char levelbuf[19];
// read power_now, set 0, read power_min, set 255, read_power_max; set 0
// we set back to 0 for safety and if restore is true we restore power_min
// otherwise we expect calling routine to be setting new power level
// we batch these commands together for speed
char *cmd = "PC;PC000;PC;PC255;PC;PC000;";
int n;
struct rig_state *rs = &rig->state;
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
retval = write_block(&rs->rigport, cmd, strlen(cmd));
if (retval != RIG_OK) { return retval; }
retval = read_string(&rs->rigport, levelbuf, sizeof(levelbuf), NULL, 0);
rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d\n", __func__, retval);
if (retval != 18)
{
rig_debug(RIG_DEBUG_ERR, "%s: expected 19, got %d in '%s'\n", __func__, retval,
levelbuf);
return -RIG_EPROTO;
}
n = sscanf(levelbuf, "PC%d;PC%d;PC%d", power_now, power_min, power_max);
if (n != 3)
{
rig_debug(RIG_DEBUG_ERR, "%s: count not parse 3 values from '%s'\n", __func__,
levelbuf);
return -RIG_EPROTO;
}
if (restore)
{
snprintf(levelbuf, sizeof(levelbuf), "PC%03d;", *power_now);
retval = kenwood_transaction(rig, levelbuf, NULL, 0);
return retval;
}
rig_debug(RIG_DEBUG_TRACE, "%s: returning now=%d, min=%d, max=%d\n", __func__,
*power_now, *power_min, *power_max);
return RIG_OK;
}
int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
{
char levelbuf[16];
@ -2198,12 +2255,16 @@ int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
switch (level)
{
case RIG_LEVEL_RFPOWER:
int power_now, power_min, power_max;
int retval;
/*
* Best estimate: 1.0 corresponds to 100W
*/
kenwood_val = val.f * 100;
case RIG_LEVEL_RFPOWER:
// Power min/max can vary so we query to find them out every time
retval = kenwood_get_power_minmax(rig, &power_now, &power_min, &power_max, 0);
if (retval != RIG_OK) { return retval; }
kenwood_val = val.f * (power_max - power_min) + power_min;
snprintf(levelbuf, sizeof(levelbuf), "PC%03d", kenwood_val);
break;
@ -2425,6 +2486,8 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
switch (level)
{
int power_now, power_min, power_max;
case RIG_LEVEL_RAWSTR:
if (RIG_IS_TS590S || RIG_IS_TS590SG)
{
@ -2562,12 +2625,13 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
break;
case RIG_LEVEL_RFPOWER:
/*
* an answer "PC100" means 100 Watt
*/
ret = get_kenwood_level(rig, "PC", NULL, &val->i);
val->f = val->i / 100.0;
return ret;
// Power min/max can vary so we query to find them out every time
retval = kenwood_get_power_minmax(rig, &power_now, &power_min, &power_max, 1);
if (retval != RIG_OK) { return retval; }
val->f = (power_now - power_min) / (float)(power_max - power_min);
return RIG_OK;
case RIG_LEVEL_AF:

Wyświetl plik

@ -27,7 +27,7 @@
#include <string.h>
#include "token.h"
#define BACKEND_VER "20200930"
#define BACKEND_VER "20201002"
#define EOM_KEN ';'
#define EOM_TH '\r'

Wyświetl plik

@ -111,9 +111,7 @@ kenwood_ts480_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
switch (level)
{
case RIG_LEVEL_RFPOWER:
kenwood_val = val.f * 100; /* level for TS480SAT is from 0.. 100W in SSB */
sprintf(levelbuf, "PC%03d", kenwood_val);
break;
return kenwood_set_level(rig, vfo, level, val);
case RIG_LEVEL_AF:
return kenwood_set_level(rig, vfo, level, val);
@ -246,29 +244,6 @@ kenwood_ts480_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
switch (level)
{
case RIG_LEVEL_RFPOWER:
retval = kenwood_transaction(rig, "PC", ackbuf, sizeof(ackbuf));
if (RIG_OK != retval)
{
return retval;
}
ack_len = strlen(ackbuf);
if (5 != ack_len)
{
return -RIG_EPROTO;
}
if (1 != sscanf(&ackbuf[2], "%d", &levelint))
{
return -RIG_EPROTO;
}
val->f = (float) levelint / 100.;
return RIG_OK;
case RIG_LEVEL_AF:
if (rig->caps->rig_model == RIG_MODEL_TS890S)
{
@ -424,6 +399,9 @@ kenwood_ts480_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
return RIG_OK;
case RIG_LEVEL_RFPOWER:
return kenwood_get_level(rig, vfo, level, val);
case RIG_LEVEL_MICGAIN:
case RIG_LEVEL_PREAMP:
case RIG_LEVEL_IF: