implement level settting and misc fixes

Hamlib-3.0
Martin Ewing 2012-02-29 23:12:42 -05:00
rodzic f3be5c4323
commit 9a36fc277d
1 zmienionych plików z 96 dodań i 113 usunięć

Wyświetl plik

@ -1,6 +1,6 @@
/* /*
* Hamlib TenTenc backend - TT-538 description * Hamlib TenTenc backend - TT-538 description
* Copyright (c) 2003-2005 by Stephane Fillod * Copyright (c) 2003-2012 by Stephane Fillod, Martin Ewing
* *
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -19,6 +19,12 @@
* *
*/ */
/* Extended and corrected by Martin Ewing AA6E 2/2012
* This backend tested with firmware v 1.330.
* Firmware version >=1.18 is probably required.
* Reference: Jupiter Model 538 Programmer's Reference Guide Rev. 1.1
*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -43,21 +49,20 @@ struct tt538_priv_data {
#define TT538_FUNCS (RIG_FUNC_NR|RIG_FUNC_ANF) #define TT538_FUNCS (RIG_FUNC_NR|RIG_FUNC_ANF)
#define TT538_LEVELS_OLD (RIG_LEVEL_RAWSTR|/*RIG_LEVEL_NB|*/ \ #define TT538_LEVELS (RIG_LEVEL_RAWSTR| \
RIG_LEVEL_RF|RIG_LEVEL_IF| \ /*RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_ANF| */ \
RIG_LEVEL_SQL| \
RIG_LEVEL_RF| \
RIG_LEVEL_AF|RIG_LEVEL_AGC| \ RIG_LEVEL_AF|RIG_LEVEL_AGC| \
RIG_LEVEL_SQL|RIG_LEVEL_ATT)
#define TT538_LEVELS (RIG_LEVEL_RAWSTR|/*RIG_LEVEL_NB|*/ \
RIG_LEVEL_SQL|/*RIG_LEVEL_IF|*/ \
RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD| \
RIG_LEVEL_RF|RIG_LEVEL_NR| \
/*RIG_LEVEL_ANF|*/RIG_LEVEL_MICGAIN| \
RIG_LEVEL_AF|RIG_LEVEL_AGC| \
RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOX| \
RIG_LEVEL_COMP|/*RIG_LEVEL_PREAMP|*/ \
RIG_LEVEL_SWR|RIG_LEVEL_ATT) RIG_LEVEL_SWR|RIG_LEVEL_ATT)
/* Note TT538 supports NB, NR, and AN levels -- to be implemented */
#define TT538_LEVELS_SET (RIG_LEVEL_SQL|RIG_LEVEL_RF| \
/*RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_ANF| */ \
RIG_LEVEL_AF| \
RIG_LEVEL_AGC|RIG_LEVEL_ATT)
#define TT538_ANTS (RIG_ANT_1) #define TT538_ANTS (RIG_ANT_1)
#define TT538_PARMS (RIG_PARM_NONE) #define TT538_PARMS (RIG_PARM_NONE)
@ -83,6 +88,7 @@ static int tt538_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width);
static int tt538_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tt538_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width);
static char which_vfo(const RIG *rig, vfo_t vfo); static char which_vfo(const RIG *rig, vfo_t vfo);
static int tt538_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int tt538_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val);
static int tt538_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val);
/* /*
* tt538 transceiver capabilities. * tt538 transceiver capabilities.
@ -91,7 +97,7 @@ static int tt538_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val);
* http://www.rfsquared.com/ * http://www.rfsquared.com/
* *
* Only set_freq is supposed to work. * Only set_freq is supposed to work.
* This is a skelton. * This is a skelton.v
*/ */
const struct rig_caps tt538_caps = { const struct rig_caps tt538_caps = {
.rig_model = RIG_MODEL_TT538, .rig_model = RIG_MODEL_TT538,
@ -118,7 +124,7 @@ const struct rig_caps tt538_caps = {
.has_get_func = TT538_FUNCS, .has_get_func = TT538_FUNCS,
.has_set_func = TT538_FUNCS, .has_set_func = TT538_FUNCS,
.has_get_level = TT538_LEVELS, .has_get_level = TT538_LEVELS,
.has_set_level = RIG_LEVEL_SET(TT538_LEVELS), .has_set_level = TT538_LEVELS_SET,
.has_get_parm = TT538_PARMS, .has_get_parm = TT538_PARMS,
.has_set_parm = TT538_PARMS, .has_set_parm = TT538_PARMS,
.level_gran = {}, /* FIXME: granularity */ .level_gran = {}, /* FIXME: granularity */
@ -186,6 +192,7 @@ const struct rig_caps tt538_caps = {
.set_mode = tt538_set_mode, .set_mode = tt538_set_mode,
.get_mode = tt538_get_mode, .get_mode = tt538_get_mode,
.get_level = tt538_get_level, .get_level = tt538_get_level,
.set_level = tt538_set_level,
.set_split_vfo = tentec2_set_split_vfo, .set_split_vfo = tentec2_set_split_vfo,
.get_split_vfo = tentec2_get_split_vfo, .get_split_vfo = tentec2_get_split_vfo,
.set_ptt = tentec2_set_ptt, .set_ptt = tentec2_set_ptt,
@ -588,7 +595,8 @@ int tt538_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
{ {
char sunits[6]; char sunits[6];
float fwd, refl, sstr; float fwd, refl, sstr;
int retval, cmd_len, lvl_len; float ratio, swr;
int retval, cmd_len, lvl_len;
unsigned char cmdbuf[16],lvlbuf[32]; unsigned char cmdbuf[16],lvlbuf[32];
@ -620,8 +628,12 @@ int tt538_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
return -RIG_EPROTO; return -RIG_EPROTO;
} }
refl = (float) lvlbuf[1]; refl = (float) lvlbuf[1];
ratio = refl / fwd;
val->f = fwd/refl; if (ratio > 0.9)
swr = 10.0; /* practical maximum SWR, avoid div by 0 */
else
swr = 1.0 / (1.0 - ratio);
val->f = swr;
break; break;
case RIG_LEVEL_RAWSTR: case RIG_LEVEL_RAWSTR:
@ -634,36 +646,13 @@ int tt538_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
__FUNCTION__, lvlbuf); __FUNCTION__, lvlbuf);
return -RIG_EPROTO; return -RIG_EPROTO;
} }
/* Jupiter returns actual S value in 1/100s of an S unit, but
#if 0 Hamlib wants an integer result. We return S units * 100 to maintain
sprintf((char *) sunits, "%c%c.%c%c", precision. */
lvlbuf[1], lvlbuf[2], lvlbuf[3], lvlbuf[4]);
sscanf(sunits, "%f", &sstr);
val->f = sstr;
printf("%f\n", val->f);
#endif
sprintf(sunits, "%c%c.%c%c", sprintf(sunits, "%c%c.%c%c",
lvlbuf[1], lvlbuf[2], lvlbuf[3], lvlbuf[4]); lvlbuf[1], lvlbuf[2], lvlbuf[3], lvlbuf[4]);
sscanf(sunits, "%f", &sstr); sscanf(sunits, "%f", &sstr);
val->i = (int) sstr; val->i = (int) (100 * sstr);
break;
case RIG_LEVEL_RFPOWER:
/* Get forward power in volts. */
lvl_len = 32;
retval = tt538_transaction (rig, "?P" EOM, 3, (char *) lvlbuf, &lvl_len);
if (retval != RIG_OK)
return retval;
if (lvlbuf[0] != 'P' || lvl_len != 4) {
rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n",
__FUNCTION__, lvlbuf);
return -RIG_EPROTO;
}
val->f = 100 * (float) lvlbuf[1] / 0xff;
break; break;
case RIG_LEVEL_AGC: case RIG_LEVEL_AGC:
@ -680,10 +669,13 @@ printf("%f\n", val->f);
return -RIG_EPROTO; return -RIG_EPROTO;
} }
switch(lvlbuf[1]) { switch(lvlbuf[1]&0xf) {
case '1': val->i=RIG_AGC_SLOW; break; /* Prog. Man. claims Jupiter returns '1', '2', and '3', but not so if
case '2': val->i=RIG_AGC_MEDIUM; break; AGC was set by program! So look at 2nd hex digit only. */
case '3': val->i=RIG_AGC_FAST; break; case 1: val->i=RIG_AGC_SLOW; break;
case 2: val->i=RIG_AGC_MEDIUM; break;
case 3: val->i=RIG_AGC_FAST; break;
default: return -RIG_EPROTO; default: return -RIG_EPROTO;
} }
break; break;
@ -706,27 +698,6 @@ printf("%f\n", val->f);
val->f = (float) lvlbuf[1] / 127; val->f = (float) lvlbuf[1] / 127;
break; break;
case RIG_LEVEL_IF:
#if 0
NO IF MONITOR??
cmd_len = sprintf((char *) cmdbuf, "?R%cP" EOM,
which_receiver(rig, vfo));
retval = tt538_transaction (rig, (char *) cmdbuf, cmd_len, (char *) lvlbuf, &lvl_len);
if (retval != RIG_OK)
return retval;
if (lvlbuf[1] != 'R' || lvlbuf[3] != 'P' || lvl_len < 5) {
rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n",
__FUNCTION__, lvlbuf);
return -RIG_EPROTO;
}
val->i = atoi(lvlbuf+4);
#endif
val->i = 0;
break;
case RIG_LEVEL_RF: case RIG_LEVEL_RF:
cmd_len = sprintf((char *) cmdbuf, "?I" EOM); cmd_len = sprintf((char *) cmdbuf, "?I" EOM);
@ -740,7 +711,9 @@ NO IF MONITOR??
__FUNCTION__, lvlbuf); __FUNCTION__, lvlbuf);
return -RIG_EPROTO; return -RIG_EPROTO;
} }
/* Note: Any RF gain over "50%" on front panel
returns 1.00 (firmware 1.281) on test rig.
However RF set level seems OK. Firmware problem? -AA6E */
val->f = 1 - (float) lvlbuf[1] / 0xff; val->f = 1 - (float) lvlbuf[1] / 0xff;
break; break;
@ -759,11 +732,6 @@ NO IF MONITOR??
val->i = lvlbuf[1]; val->i = lvlbuf[1];
break; break;
case RIG_LEVEL_PREAMP:
/* Receiver does not contain a preamp */
val->i=0;
break;
case RIG_LEVEL_SQL: case RIG_LEVEL_SQL:
cmd_len = sprintf((char *) cmdbuf, "?H" EOM); cmd_len = sprintf((char *) cmdbuf, "?H" EOM);
@ -779,43 +747,6 @@ NO IF MONITOR??
val->f = ((float) lvlbuf[1] / 127); val->f = ((float) lvlbuf[1] / 127);
break; break;
case RIG_LEVEL_MICGAIN:
lvl_len = 3;
retval = tt538_transaction (rig, "?O" EOM, 3, (char *) lvlbuf, &lvl_len);
if (retval != RIG_OK)
return retval;
if (lvlbuf[0] != 'O' || lvl_len != 3) {
rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n",
__FUNCTION__, lvlbuf);
return -RIG_EPROTO;
}
val->f = (float) lvlbuf[2] / 0x0f;
break;
case RIG_LEVEL_COMP:
/* Query S units signal level. */
lvl_len = 32;
retval = tt538_transaction (rig, "?S" EOM, 3, (char *) lvlbuf, &lvl_len);
if (retval != RIG_OK)
return retval;
if (lvlbuf[0] != 'S' || lvl_len != 6) {
rig_debug(RIG_DEBUG_ERR,"%s: unexpected answer '%s'\n",
__FUNCTION__, lvlbuf);
return -RIG_EPROTO;
}
sprintf((char *) sunits, "%c%c.%c%c",
lvlbuf[1], lvlbuf[2], lvlbuf[3], lvlbuf[4]);
sscanf(sunits, "%f", &sstr);
printf("%f\n", sstr);
val->f = sstr;
break;
default: default:
rig_debug(RIG_DEBUG_ERR,"%s: unsupported level %d\n", rig_debug(RIG_DEBUG_ERR,"%s: unsupported level %d\n",
__FUNCTION__, level); __FUNCTION__, level);
@ -825,3 +756,55 @@ printf("%f\n", sstr);
return RIG_OK; return RIG_OK;
} }
/*
* tt538_set_level
* Assumes rig!=NULL, val!=NULL
*/
int tt538_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
{
char cc, cmdbuf[32];
int cmd_len, retval;
switch (level) {
case RIG_LEVEL_AGC:
switch(val.i) {
case RIG_AGC_FAST: cc = '3'; break;
case RIG_AGC_MEDIUM: cc = '2'; break;
case RIG_AGC_SLOW: cc = '1'; break;
default: cc = '2';
}
cmd_len = sprintf(cmdbuf, "*G%c" EOM, cc);
printf("*G%c\n", cc);
break;
case RIG_LEVEL_AF:
cmd_len = sprintf(cmdbuf, "*U%c" EOM, (int)(127 * val.f));
break;
case RIG_LEVEL_RF:
cmd_len = sprintf(cmdbuf, "*I%c" EOM, (int)(127 * val.f));
break;
case RIG_LEVEL_ATT:
if (val.i)
cc = '1';
else
cc = '0';
cmd_len = sprintf(cmdbuf, "*J%c" EOM, cc);
break;
case RIG_LEVEL_SQL:
cmd_len = sprintf(cmdbuf, "*H%c" EOM, (int)(127 * val.f));
break;
default:
rig_debug(RIG_DEBUG_ERR,"%s: unsupported level %d\n",
__FUNCTION__, level);
return -RIG_EINVAL;
}
retval = tt538_transaction (rig, cmdbuf, cmd_len, NULL,NULL);
if (retval != RIG_OK)
return retval;
return RIG_OK;
}