kopia lustrzana https://github.com/Hamlib/Hamlib
prm80 : more feature coverage and fixes
Tested-by: Claus <claus.moessner@web.de>pull/588/head
rodzic
709f281005
commit
ff9c1badfa
|
@ -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 ..
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
||||
};
|
||||
|
|
Ładowanie…
Reference in New Issue