prm80 : more feature coverage and fixes

Tested-by: Claus <claus.moessner@web.de>
pull/588/head
Stephane Fillod 2021-03-06 10:14:17 +01:00
rodzic 709f281005
commit ff9c1badfa
3 zmienionych plików z 259 dodań i 42 usunięć

Wyświetl plik

@ -551,33 +551,19 @@ static int hhtoi(const char *p)
return (int)strtol(buf, NULL, 16);
}
/*
* prm80_get_channel
* Assumes rig!=NULL
/**
* Get system state [E] from rig into \a statebuf
*/
int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only)
static int prm80_read_system_state(hamlib_port_t *rigport, char *statebuf)
{
struct prm80_priv_data *priv = (struct prm80_priv_data *)rig->state.priv;
struct rig_state *rs = &rig->state;
char statebuf[BUFSZ];
char *p;
int ret, chanstate, mode_byte, lock_byte;
if (chan->vfo == RIG_VFO_MEM)
{
ret = prm80_set_mem(rig, RIG_VFO_CURR, chan->channel_num);
if (ret != RIG_OK)
{
return ret;
}
}
int ret;
// Get rid of possible prompt sent by the rig
rig_flush(&rs->rigport);
rig_flush(rigport);
/* [E] = Show system state */
ret = write_block(&rs->rigport, "E", 1);
ret = write_block(rigport, "E", 1);
if (ret < 0)
{
@ -585,7 +571,7 @@ int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only)
}
// The response length is fixed
ret = read_block(&rs->rigport, statebuf, 20);
ret = read_block(rigport, statebuf, 20);
if (ret < 0)
{
@ -610,9 +596,13 @@ int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only)
{
int left_to_read = (p - statebuf) + 1;
memmove(statebuf, p + 1, 20 - left_to_read);
ret = read_block(&rs->rigport, statebuf + 20 - left_to_read, left_to_read);
ret = read_block(rigport, statebuf + 20 - left_to_read, left_to_read);
if (ret >= 0)
if (ret < 0)
{
return ret;
}
else if (ret >= 0)
{
statebuf[20] = '\0';
}
@ -621,6 +611,38 @@ int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only)
statebuf);
}
return RIG_OK;
}
/*
* prm80_get_channel
* Assumes rig!=NULL
*/
int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only)
{
struct prm80_priv_data *priv = (struct prm80_priv_data *)rig->state.priv;
struct rig_state *rs = &rig->state;
char statebuf[BUFSZ];
int ret, chanstate, mode_byte, lock_byte;
if (chan->vfo == RIG_VFO_MEM)
{
ret = prm80_set_mem(rig, RIG_VFO_CURR, chan->channel_num);
if (ret != RIG_OK)
{
return ret;
}
}
ret = prm80_read_system_state(&rs->rigport, statebuf);
if (ret != RIG_OK)
{
return ret;
}
/* (Mode-Chan-Chanstate-Sql-Vol-Lock-RX freq-TX freq). */
/* Examples: 1240080AFF0033F02D40 or 14000C00FD0079708020 */
@ -654,10 +676,12 @@ int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only)
chan->levels[LVL_AF].f = ((float)(hhtoi(statebuf + 8) >> 4)) / 15.;
chan->levels[LVL_RFPOWER].f = (mode_byte & 0x02) ? 1.0 : 0.0;
chan->funcs = 0;
chan->funcs |= (chanstate & 0x02) ? RIG_FUNC_REV : 0;
lock_byte = hhtoi(statebuf + 10) & 0x0f;
chan->funcs = (lock_byte != 0) ? RIG_FUNC_LOCK : 0;
chan->funcs |= (lock_byte & 0x05) ? RIG_FUNC_LOCK : 0;
chan->funcs |= (lock_byte & 0x08) ? RIG_FUNC_MUTE : 0;
chan->freq = ((hhtoi(statebuf + 12) << 8) + hhtoi(statebuf + 14)) * FREQ_DIV +
RX_IF_OFFSET;
@ -805,7 +829,8 @@ int prm80_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan)
#endif
ret = prm80_set_func(rig, vfo, RIG_FUNC_LOCK, chan->funcs & RIG_FUNC_LOCK);
ret = prm80_set_func(rig, vfo, RIG_FUNC_LOCK,
!!(chan->funcs & RIG_FUNC_LOCK));
if (ret != RIG_OK)
{
@ -817,15 +842,21 @@ int prm80_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan)
}
// TODO FUNC_REV ?
// TODO FUNC_REV through Channel state byte ?
// TODO "Read-Modify-Write" (or shadowing in priv area) of the lock bits
int prm80_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
{
int ret;
if (func & RIG_FUNC_LOCK)
{
/* Lock keys/TX/Vol */
ret = prm80_transaction(rig, "K", (status != 0) ? "03" : "00", 1);
/* Lock keys(b0)/Vol(b2) */
ret = prm80_transaction(rig, "K", (status != 0) ? "05" : "00", 1);
}
else if (func & RIG_FUNC_MUTE)
{
/* Lock RX(b3) */
ret = prm80_transaction(rig, "K", (status != 0) ? "08" : "00", 1);
}
else
{
@ -850,7 +881,7 @@ int prm80_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status)
return ret;
}
*status = (chan.funcs & func);
*status = !!(chan.funcs & func);
return RIG_OK;
}
@ -862,6 +893,7 @@ int prm80_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status)
int prm80_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
{
char buf[BUFSZ];
int ret, mode_byte;
// do some clamping, all levels are float values.
if (val.f < 0.0)
@ -886,19 +918,28 @@ int prm80_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
return prm80_transaction(rig, "F", buf, 1);
case RIG_LEVEL_RFPOWER:
// TODO : modify the Mode byte b1 ?
#if 0
/* Current mode:
; b0: Squelch b1: power
; b2: Squelch open b3: TX
; b4: PLL locked b5: Long press memorize
; b6: Debouncing in effect b7: LCD refresh
*/
// TODO perform a "Read-Modify-Write" of the mode_byte
mode_byte = 0x10;
mode_byte |= (chan->levels[LVL_RFPOWER].f == 0.) ? 0 : 0x02;
#endif
return -RIG_ENIMPL;
// Perform a "Read-Modify-Write" of the mode_byte
ret = prm80_read_system_state(&rig->state.rigport, buf);
if (ret != RIG_OK)
{
return ret;
}
prm80_wait_for_prompt(&rig->state.rigport);
mode_byte = hhtoi(buf);
mode_byte &= ~0x02;
mode_byte |= (val.f == 0.) ? 0 : 0x02;
sprintf(buf, "%02X", (unsigned)mode_byte);
return prm80_transaction(rig, "D", buf, 1);
default:
rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__,
@ -909,6 +950,106 @@ int prm80_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
return RIG_OK;
}
/*
* get_level RIG_LEVEL_RAWSTR
*/
static int prm80_get_rawstr_RAM(RIG *rig, value_t *val)
{
char buf[BUFSZ];
struct rig_state *rs = &rig->state;
int ret, i;
/* [U] = Print 80c552 internal RAM. */
// Send cmd, Wait for colon prompt, but then send nothing
ret = prm80_transaction(rig, "U", "", 0);
if (ret < 0)
{
return ret;
}
// Read CRLF
ret = read_string(&rs->rigport, buf, BUFSZ, "\n", 1);
if (ret < 0)
{
return ret;
}
// (16 lines of 16 bytes each)
// According to prm.a51, the rssi_hold variable is in RAM at RAM+35.
// The RAM base is at 030h.
#define RSSI_HOLD_ADDR (0x30 + 35) // = 0x53
for (i = 0; i < (RSSI_HOLD_ADDR / 16) + 1; i++)
{
ret = read_string(&rs->rigport, buf, BUFSZ, "\n", 1);
if (ret < 0)
{
return ret;
}
}
// A line looks like this
// "$50 : 00 01 02 53 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\r\n"
val->i = hhtoi(buf + 6 + 3 * (RSSI_HOLD_ADDR % 16));
// discard the remaining content of RAM print
for (i = 0; i < (16 - RSSI_HOLD_ADDR / 16) - 1; i++)
{
ret = read_string(&rs->rigport, buf, BUFSZ, "\n", 1);
}
prm80_wait_for_prompt(&rs->rigport);
return RIG_OK;
}
/*
* get_level RIG_LEVEL_RAWSTR
*/
static int prm80_get_rawstr(RIG *rig, value_t *val)
{
char buf[BUFSZ];
struct rig_state *rs = &rig->state;
int ret, i;
// Get rid of possible prompt sent by the rig
rig_flush(&rs->rigport);
/* [A] = RSSI */
ret = write_block(&rs->rigport, "A", 1);
if (ret < 0)
{
RETURNFUNC(ret);
}
// The response length is fixed
ret = read_block(&rs->rigport, buf, 4);
if (ret < 0)
{
return ret;
}
if (ret >= 0)
{
buf[ret] = '\0';
}
val->i = hhtoi(buf);
prm80_wait_for_prompt(&rs->rigport);
return RIG_OK;
}
/*
* prm80_get_level
* Assumes rig!=NULL
@ -918,6 +1059,12 @@ int prm80_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
int ret;
channel_t chan;
// Get rawstr apart, it is not read from system state
if (level == RIG_LEVEL_RAWSTR)
{
return prm80_get_rawstr(rig, val);
}
memset(&chan, 0, sizeof(chan));
chan.vfo = RIG_VFO_CURR;
@ -954,6 +1101,50 @@ int prm80_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
return RIG_OK;
}
int prm80_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
{
char statebuf[BUFSZ];
int ret, mode_byte;
ret = prm80_read_system_state(&rig->state.rigport, statebuf);
if (ret != RIG_OK)
{
return ret;
}
mode_byte = hhtoi(statebuf);
// TX mode on?
*ptt = (mode_byte & 0x08) ? RIG_PTT_ON : RIG_PTT_OFF;
prm80_wait_for_prompt(&rig->state.rigport);
return RIG_OK;
}
int prm80_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd)
{
char statebuf[BUFSZ];
int ret, mode_byte;
ret = prm80_read_system_state(&rig->state.rigport, statebuf);
if (ret != RIG_OK)
{
return ret;
}
mode_byte = hhtoi(statebuf);
// Squelch open?
*dcd = (mode_byte & 0x04) ? RIG_DCD_ON : RIG_DCD_OFF;
prm80_wait_for_prompt(&rig->state.rigport);
return RIG_OK;
}
// TODO vfo_op : MCL FROM_VFO ..
/*

Wyświetl plik

@ -24,7 +24,7 @@
#include <hamlib/rig.h>
#define BACKEND_VER "20210217"
#define BACKEND_VER "20210220"
#define PRM80_MEM_CAP { \
.freq = 1, \
@ -57,6 +57,8 @@ int prm80_set_mem(RIG *rig, vfo_t vfo, int ch);
int prm80_get_mem(RIG *rig, vfo_t vfo, int *ch);
int prm80_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan);
int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only);
int prm80_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd);
int prm80_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt);
const char *prm80_get_info(RIG *rig);

Wyświetl plik

@ -33,9 +33,9 @@
#define PRM8060_ALL_MODES (RIG_MODE_FM)
#define PRM8060_FUNC (RIG_FUNC_REV|RIG_FUNC_LOCK)
#define PRM8060_FUNC (RIG_FUNC_REV|RIG_FUNC_LOCK|RIG_FUNC_MUTE)
#define PRM8060_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_SQL /* |RIG_LEVEL_RFPOWER */)
#define PRM8060_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER)
#define PRM8060_PARM_ALL (RIG_PARM_NONE)
@ -44,6 +44,26 @@
#define PRM8060_VFO (RIG_VFO_MEM)
// Calibration done on PRM8070
#define PRM8060_STR_CAL { 15, \
{ \
{ 0x14, -54 }, /* S0 */ \
{ 0x1D, -48 }, /* S1 */ \
{ 0x26, -42 }, /* S2 */ \
{ 0x33, -36 }, /* S3 */ \
{ 0x3F, -30 }, /* S4 */ \
{ 0x4D, -24 }, /* S5 */ \
{ 0x55, -18 }, /* S6 */ \
{ 0x61, -12 }, /* S7 */ \
{ 0x68, -6 }, /* S8 */ \
{ 0x6C, 0 }, /* S9 */ \
{ 0x81, 10 }, /* +10 */ \
{ 0x8B, 20 }, /* +20 */ \
{ 0x8C, 40 }, /* +40 */ \
{ 0x8C, 50 }, /* +50 */ \
{ 0xFF, 60 } /* +60 */ \
} }
/*
* PRM 8060 rig capabilities.
* http://prm80.sourceforge.net/
@ -58,8 +78,8 @@ const struct rig_caps prm8060_caps =
.copyright = "LGPL",
.status = RIG_STATUS_BETA,
.rig_type = RIG_TYPE_TRANSCEIVER,
.ptt_type = RIG_PTT_NONE,
.dcd_type = RIG_DCD_NONE,
.ptt_type = RIG_PTT_RIG,
.dcd_type = RIG_DCD_RIG,
.port_type = RIG_PORT_SERIAL,
.serial_rate_min = 4800,
.serial_rate_max = 4800,
@ -74,7 +94,7 @@ const struct rig_caps prm8060_caps =
.has_get_func = PRM8060_FUNC,
.has_set_func = PRM8060_FUNC,
.has_get_level = PRM8060_LEVEL_ALL | RIG_LEVEL_RFPOWER,
.has_get_level = PRM8060_LEVEL_ALL | RIG_LEVEL_RAWSTR,
.has_set_level = RIG_LEVEL_SET(PRM8060_LEVEL_ALL),
.has_get_parm = PRM8060_PARM_ALL,
.has_set_parm = RIG_PARM_SET(PRM8060_PARM_ALL),
@ -120,6 +140,8 @@ const struct rig_caps prm8060_caps =
RIG_FLT_END,
},
.str_cal = PRM8060_STR_CAL,
.rig_init = prm80_init,
.rig_cleanup = prm80_cleanup,
.get_mode = prm80_get_mode,
@ -138,6 +160,8 @@ const struct rig_caps prm8060_caps =
.set_level = prm80_set_level,
.get_level = prm80_get_level,
.reset = prm80_reset,
.get_dcd = prm80_get_dcd,
.get_ptt = prm80_get_ptt,
.get_info = prm80_get_info,
};