mirror of
https://github.com/Hamlib/Hamlib
synced 2026-08-13 17:32:05 -04:00
QMX: read power meter full scale from the radio
QMX_MAX_POWER was hardcoded to 5.0f, taken from the "5W class radio" description. That is not the figure the hardware meters against: the QMX power meter full scale is a user setting, 6W on a stock radio and 12W on one carrying the PA0RDT 4+4 BS170 PA modification. A stock QMX at full output therefore reported RFPOWER_METER as 1.2 rather than 1.0. The radio will say which it is, via the Menu Manager command: MMDisplay/controls|Pwr/SWR display|Power fullscale; -> MM6W; qrplabs_qmx_open wraps qrplabs_open (which stays shared with the QCX/QDX caps) to probe it once and keep the answer in level_gran[LVL_RFPOWER_METER_WATTS].max, which is both where the value belongs and where get_level can find it again -- no extra field in the shared kenwood_priv_data. rig_init copies level_gran out of caps long before caps->rig_open runs, so the override sticks. The probe is optional, so question_mark_response_means_rejected is set across it, following ts590.c. Firmware predating MM answers "?;" and would otherwise burn the full retry budget on every open; instead it fails immediately and the 6W default declared in the caps stands. RFPOWER_METER_WATTS is unchanged -- PC; returns absolute watts, and the full scale setting only ever scaled the front panel bar graph. Tested against a QMX running firmware 1_04_005QMX, which reports 6W. The 12W branch is untested for want of a modified radio. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
55635bd67d
commit
d0ee1dcd2e
2 changed files with 78 additions and 7 deletions
4
NEWS
4
NEWS
|
|
@ -10,7 +10,9 @@ Please send Hamlib bug reports to hamlib-developer@lists.sourceforge.net
|
|||
|
||||
Version 5.x -- future
|
||||
* QMX: Add SWR and RF power meter readback using the QRP Labs
|
||||
SW and PC CAT commands.
|
||||
SW and PC CAT commands. The power meter full scale (6W stock,
|
||||
12W with the PA0RDT PA modification) is read from the radio at
|
||||
open time.
|
||||
* rig_get_conf deprecated and replaced by rig_get_conf2
|
||||
* rot_get_conf deprecated and replaced by rot_get_conf2
|
||||
* Change FT1000MP Mark V model names to align with FT1000MP
|
||||
|
|
|
|||
|
|
@ -38,8 +38,16 @@
|
|||
#define PS8000A_ALL_MODES (RIG_MODE_AM|RIG_MODE_AMS|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR)
|
||||
#define QMX_ALL_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB)
|
||||
#define QMX_LEVEL_GET (RIG_LEVEL_SWR|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS)
|
||||
/* QMX is a 5W class radio -- used to scale RFPOWER_METER to 0.0..1.0 */
|
||||
#define QMX_MAX_POWER 5.0f
|
||||
/*
|
||||
* Full scale of the QMX power meter, used to scale RFPOWER_METER to 0.0..1.0.
|
||||
* 6W is the stock value; a radio carrying the PA0RDT 4+4 BS170 PA modification
|
||||
* reports 12W instead. qrplabs_qmx_open asks the radio which it is, so this is
|
||||
* only the fallback for firmware too old to answer.
|
||||
*/
|
||||
#define QMX_DEFAULT_MAX_POWER 6.0f
|
||||
/* Menu Manager path to the setting, see the QMX CAT manual */
|
||||
#define QMX_POWER_FULLSCALE_CMD \
|
||||
"MMDisplay/controls|Pwr/SWR display|Power fullscale"
|
||||
|
||||
#define TS480_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY)
|
||||
#define TS480_AM_TX_MODES RIG_MODE_AM
|
||||
|
|
@ -1299,6 +1307,60 @@ static int qrplabs_get_clock(RIG *rig, int *year, int *month, int *day, int *hou
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* The QMX power meter has a configurable full scale reading: 6W for a stock
|
||||
* radio, 12W for one carrying the PA0RDT 4+4 BS170 PA modification. Ask the
|
||||
* radio which it is, so RIG_LEVEL_RFPOWER_METER scales against the right value,
|
||||
* and keep the answer in level_gran where get_level can find it again.
|
||||
* Firmware predating the Menu Manager command answers "?;" -- in that case the
|
||||
* default declared in the caps stands.
|
||||
*/
|
||||
static int qrplabs_qmx_open(RIG *rig)
|
||||
{
|
||||
struct kenwood_priv_data *priv = (struct kenwood_priv_data *) STATE(rig)->priv;
|
||||
char buf[KENWOOD_MAX_BUF_LEN];
|
||||
int retval;
|
||||
float fullscale;
|
||||
|
||||
ENTERFUNC;
|
||||
|
||||
retval = qrplabs_open(rig);
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
RETURNFUNC(retval);
|
||||
}
|
||||
|
||||
/* the probe is optional, so take "?;" at face value rather than retrying */
|
||||
priv->question_mark_response_means_rejected = 1;
|
||||
retval = kenwood_transaction(rig, QMX_POWER_FULLSCALE_CMD, buf, sizeof(buf));
|
||||
priv->question_mark_response_means_rejected = 0;
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"%s: power fullscale unavailable (%s), assuming %.0fW\n", __func__,
|
||||
rigerror(retval), QMX_DEFAULT_MAX_POWER);
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
|
||||
/* the reply carries the value of the setting, e.g. MM6W; or MM12W; */
|
||||
if (strlen(buf) <= 2 || sscanf(buf + 2, "%f", &fullscale) != 1
|
||||
|| fullscale <= 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR,
|
||||
"%s: unable to parse power fullscale from '%s', assuming %.0fW\n",
|
||||
__func__, buf, QMX_DEFAULT_MAX_POWER);
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: power meter fullscale %.0fW\n", __func__,
|
||||
fullscale);
|
||||
STATE(rig)->level_gran[LVL_RFPOWER_METER_WATTS].max.f = fullscale;
|
||||
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* QMX-specific meter readings.
|
||||
* SW; returns the SWR in hundredths, e.g. SW121; means 1.21:1
|
||||
|
|
@ -1312,6 +1374,7 @@ static int qrplabs_qmx_get_level(RIG *rig, vfo_t vfo, setting_t level,
|
|||
char lvlbuf[16];
|
||||
int retval;
|
||||
int raw;
|
||||
float fullscale;
|
||||
|
||||
ENTERFUNC;
|
||||
|
||||
|
|
@ -1372,7 +1435,12 @@ static int qrplabs_qmx_get_level(RIG *rig, vfo_t vfo, setting_t level,
|
|||
|
||||
if (level == RIG_LEVEL_RFPOWER_METER)
|
||||
{
|
||||
val->f /= QMX_MAX_POWER; /* 0.0..1.0 */
|
||||
/* full scale as discovered by qrplabs_qmx_open */
|
||||
fullscale = STATE(rig)->level_gran[LVL_RFPOWER_METER_WATTS].max.f;
|
||||
|
||||
if (fullscale <= 0) { fullscale = QMX_DEFAULT_MAX_POWER; }
|
||||
|
||||
val->f /= fullscale; /* 0.0..1.0 */
|
||||
}
|
||||
|
||||
RETURNFUNC(RIG_OK);
|
||||
|
|
@ -2035,7 +2103,7 @@ struct rig_caps qrplabs_qmx_caps =
|
|||
RIG_MODEL(RIG_MODEL_QRPLABS_QMX),
|
||||
.model_name = "QMX",
|
||||
.mfg_name = "QRPLabs",
|
||||
.version = BACKEND_VER ".3",
|
||||
.version = BACKEND_VER ".4",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_BETA,
|
||||
.rig_type = RIG_TYPE_TRANSCEIVER,
|
||||
|
|
@ -2082,13 +2150,14 @@ struct rig_caps qrplabs_qmx_caps =
|
|||
#undef NO_LVL_RFPOWER_METER_WATTS
|
||||
/* SW; and PC; report in hundredths and tenths respectively */
|
||||
[LVL_SWR] = {.min = {.f = 0}, .max = {.f = 99.99f}, .step = {.f = 0.01f}},
|
||||
[LVL_RFPOWER_METER_WATTS] = {.min = {.f = 0}, .max = {.f = QMX_MAX_POWER}, .step = {.f = 0.1f}},
|
||||
/* max is the meter full scale, refined at open time -- see qrplabs_qmx_open */
|
||||
[LVL_RFPOWER_METER_WATTS] = {.min = {.f = 0}, .max = {.f = QMX_DEFAULT_MAX_POWER}, .step = {.f = 0.1f}},
|
||||
},
|
||||
|
||||
.priv = (void *)& ts480_priv_caps,
|
||||
|
||||
.rig_init = ts480_init,
|
||||
.rig_open = qrplabs_open,
|
||||
.rig_open = qrplabs_qmx_open,
|
||||
.rig_cleanup = kenwood_cleanup,
|
||||
.set_freq = kenwood_set_freq,
|
||||
.get_freq = kenwood_get_freq,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue