kopia lustrzana https://github.com/Hamlib/Hamlib
Pretty much a complete re-write of thd72.c, since the old one didn't
work at all. Many commands have been tested with real hardware. But more work remains to be done.pull/26/head
rodzic
5f05a0491e
commit
e970be4350
667
kenwood/thd72.c
667
kenwood/thd72.c
|
@ -1,8 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Hamlib Kenwood backend - TH-D72 description
|
* Hamlib Kenwood TH-D72 backend
|
||||||
* cloned after TH-D7
|
|
||||||
* Copyright (c) 2000-2011 by Stephane Fillod
|
* Copyright (c) 2000-2011 by Stephane Fillod
|
||||||
*
|
* Copyright (c) 2018 by Brian Lucas
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -33,10 +32,11 @@
|
||||||
#include "num_stdio.h"
|
#include "num_stdio.h"
|
||||||
#include "iofunc.h"
|
#include "iofunc.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
||||||
#define THD72_MODES (RIG_MODE_FM|RIG_MODE_AM)
|
#define THD72_MODES (RIG_MODE_FM|RIG_MODE_AM)
|
||||||
#define THD72_MODES_TX (RIG_MODE_FM)
|
#define THD72_MODES_TX (RIG_MODE_FM)
|
||||||
|
|
||||||
#define THD72_FUNC_ALL (RIG_FUNC_TSQL| \
|
#define THD72_FUNC_ALL (RIG_FUNC_TSQL| \
|
||||||
RIG_FUNC_AIP| \
|
RIG_FUNC_AIP| \
|
||||||
|
@ -47,148 +47,446 @@
|
||||||
RIG_FUNC_LOCK| \
|
RIG_FUNC_LOCK| \
|
||||||
RIG_FUNC_ARO)
|
RIG_FUNC_ARO)
|
||||||
|
|
||||||
#define THD72_LEVEL_ALL (RIG_LEVEL_STRENGTH| \
|
#define THD72_LEVEL_ALL (RIG_LEVEL_RFPOWER|\
|
||||||
RIG_LEVEL_SQL| \
|
RIG_LEVEL_VOXGAIN|\
|
||||||
RIG_LEVEL_AF| \
|
RIG_LEVEL_VOXDELAY)
|
||||||
RIG_LEVEL_RF|\
|
|
||||||
RIG_LEVEL_MICGAIN)
|
|
||||||
|
|
||||||
#define THD72_PARMS (RIG_PARM_BACKLIGHT)
|
#define THD72_PARMS (RIG_PARM_BACKLIGHT)
|
||||||
|
|
||||||
#define THD72_VFO_OP (RIG_OP_NONE)
|
#define THD72_VFO_OP (RIG_OP_NONE)
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: Band A & B
|
|
||||||
*/
|
|
||||||
#define THD72_VFO (RIG_VFO_A|RIG_VFO_B)
|
#define THD72_VFO (RIG_VFO_A|RIG_VFO_B)
|
||||||
|
|
||||||
static rmode_t td72_mode_table[KENWOOD_MODE_TABLE_MAX] = {
|
static rmode_t thd72_mode_table[3] = {
|
||||||
[0] = RIG_MODE_FM,
|
[0] = RIG_MODE_WFM,
|
||||||
[1] = RIG_MODE_AM,
|
[1] = RIG_MODE_FM,
|
||||||
|
[2] = RIG_MODE_AM,
|
||||||
|
};
|
||||||
|
|
||||||
|
static pbwidth_t thd72_width_table[3] = {
|
||||||
|
[0] = 10000, // +-5KHz
|
||||||
|
[1] = 5000, // +-2.5KHz
|
||||||
|
[2] = 10000, // what should this be?
|
||||||
|
};
|
||||||
|
|
||||||
|
static rptr_shift_t thd72_rshf_table[3] = {
|
||||||
|
[0] = RIG_RPT_SHIFT_NONE,
|
||||||
|
[1] = RIG_RPT_SHIFT_PLUS,
|
||||||
|
[2] = RIG_RPT_SHIFT_MINUS,
|
||||||
|
} ;
|
||||||
|
static int thd72voxdelay[7] = {
|
||||||
|
[0] = 2500,
|
||||||
|
[1] = 5000,
|
||||||
|
[2] = 7500,
|
||||||
|
[3] = 10000,
|
||||||
|
[4] = 15000,
|
||||||
|
[5] = 20000,
|
||||||
|
[6] = 30000
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct kenwood_priv_caps thd72_priv_caps = {
|
static struct kenwood_priv_caps thd72_priv_caps = {
|
||||||
.cmdtrm = EOM_TH, /* Command termination character */
|
.cmdtrm = EOM_TH, /* Command termination character */
|
||||||
.mode_table = td72_mode_table,
|
.mode_table = thd72_mode_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int thd72_open(RIG *rig);
|
|
||||||
static int thd72_get_chan_all_cb (RIG * rig, chan_cb_t chan_cb, rig_ptr_t arg);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* th-d72a rig capabilities.
|
|
||||||
*/
|
|
||||||
const struct rig_caps thd72a_caps = {
|
|
||||||
.rig_model = RIG_MODEL_THD72A,
|
|
||||||
.model_name = "TH-D72A",
|
|
||||||
.mfg_name = "Kenwood",
|
|
||||||
.version = TH_VER ".1",
|
|
||||||
.copyright = "LGPL",
|
|
||||||
.status = RIG_STATUS_ALPHA,
|
|
||||||
.rig_type = RIG_TYPE_HANDHELD|RIG_FLAG_APRS|RIG_FLAG_TNC|RIG_FLAG_DXCLUSTER,
|
|
||||||
.ptt_type = RIG_PTT_RIG,
|
|
||||||
.dcd_type = RIG_DCD_RIG,
|
|
||||||
.port_type = RIG_PORT_SERIAL,
|
|
||||||
.serial_rate_min = 9600,
|
|
||||||
.serial_rate_max = 9600,
|
|
||||||
.serial_data_bits = 8,
|
|
||||||
.serial_stop_bits = 1,
|
|
||||||
.serial_parity = RIG_PARITY_NONE,
|
|
||||||
.serial_handshake = RIG_HANDSHAKE_XONXOFF,
|
|
||||||
.write_delay = 0,
|
|
||||||
.post_write_delay = 0,
|
|
||||||
.timeout = 250,
|
|
||||||
.retry = 3,
|
|
||||||
|
|
||||||
.has_get_func = THD72_FUNC_ALL,
|
|
||||||
.has_set_func = THD72_FUNC_ALL,
|
|
||||||
.has_get_level = THD72_LEVEL_ALL,
|
|
||||||
.has_set_level = RIG_LEVEL_SET(THD72_LEVEL_ALL),
|
|
||||||
.has_get_parm = THD72_PARMS,
|
|
||||||
.has_set_parm = THD72_PARMS, /* FIXME: parms */
|
|
||||||
.level_gran = {
|
|
||||||
[LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 5 } },
|
|
||||||
[LVL_SQL] = { .min = { .i = 0 }, .max = { .i = 5 } },
|
|
||||||
[LVL_RFPOWER] = { .min = { .i = 3 }, .max = { .i = 0 } },
|
|
||||||
},
|
|
||||||
.parm_gran = {},
|
|
||||||
.ctcss_list = kenwood38_ctcss_list,
|
|
||||||
.dcs_list = NULL,
|
|
||||||
.preamp = { RIG_DBLST_END, },
|
|
||||||
.attenuator = { RIG_DBLST_END, },
|
|
||||||
.max_rit = Hz(0),
|
|
||||||
.max_xit = Hz(0),
|
|
||||||
.max_ifshift = Hz(0),
|
|
||||||
.vfo_ops = THD72_VFO_OP,
|
|
||||||
.targetable_vfo = RIG_TARGETABLE_FREQ,
|
|
||||||
.transceive = RIG_TRN_RIG,
|
|
||||||
.bank_qty = 0,
|
|
||||||
.chan_desc_sz = 6, /* TBC */
|
|
||||||
|
|
||||||
.chan_list = {
|
|
||||||
{ 0, 999, RIG_MTYPE_MEM , {TH_CHANNEL_CAPS}}, /* TBC MEM */
|
|
||||||
RIG_CHAN_END,
|
|
||||||
},
|
|
||||||
|
|
||||||
.rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */
|
|
||||||
.tx_range_list1 = { RIG_FRNG_END, },
|
|
||||||
.rx_range_list2 = {
|
|
||||||
{MHz(118),MHz(174),THD72_MODES,-1,-1,THD72_VFO},
|
|
||||||
{MHz(320),MHz(524),THD72_MODES,-1,-1,THD72_VFO},
|
|
||||||
RIG_FRNG_END,
|
|
||||||
}, /* rx range */
|
|
||||||
.tx_range_list2 = {
|
|
||||||
{MHz(144),MHz(148),THD72_MODES_TX,W(0.05),W(5),THD72_VFO},
|
|
||||||
{MHz(430),MHz(440),THD72_MODES_TX,W(0.05),W(5),THD72_VFO},
|
|
||||||
RIG_FRNG_END,
|
|
||||||
}, /* tx range */
|
|
||||||
|
|
||||||
.tuning_steps = {
|
|
||||||
{THD72_MODES,kHz(5)},
|
|
||||||
{THD72_MODES,kHz(6.25)},
|
|
||||||
/* kHz(8.33) ?? */
|
|
||||||
{THD72_MODES,kHz(10)},
|
|
||||||
{THD72_MODES,kHz(12.5)},
|
|
||||||
{THD72_MODES,kHz(15)},
|
|
||||||
{THD72_MODES,kHz(20)},
|
|
||||||
{THD72_MODES,kHz(25)},
|
|
||||||
{THD72_MODES,kHz(30)},
|
|
||||||
{THD72_MODES,kHz(50)},
|
|
||||||
{THD72_MODES,kHz(100)},
|
|
||||||
RIG_TS_END,
|
|
||||||
},
|
|
||||||
/* mode/filter list, remember: order matters! */
|
|
||||||
.filters = {
|
|
||||||
{RIG_MODE_FM, kHz(14)},
|
|
||||||
{RIG_MODE_AM, kHz(9)},
|
|
||||||
RIG_FLT_END,
|
|
||||||
},
|
|
||||||
.priv = (void *)&thd72_priv_caps,
|
|
||||||
|
|
||||||
.rig_init = kenwood_init,
|
|
||||||
.rig_cleanup = kenwood_cleanup,
|
|
||||||
.rig_open = thd72_open,
|
|
||||||
.set_vfo = th_set_vfo,
|
|
||||||
.get_vfo = th_get_vfo,
|
|
||||||
|
|
||||||
.get_chan_all_cb = thd72_get_chan_all_cb,
|
|
||||||
|
|
||||||
.get_info = th_get_info,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int thd72_open(RIG *rig)
|
int thd72_open(RIG *rig)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
struct kenwood_priv_data *priv = rig->state.priv;
|
||||||
|
strcpy (priv->verify_cmd, "ID\r");
|
||||||
|
|
||||||
kenwood_transaction(rig, "", NULL, 0);
|
ret = kenwood_transaction(rig, "", NULL, 0);
|
||||||
|
|
||||||
ret = kenwood_transaction(rig, "TC1", NULL, 0);
|
return ret;
|
||||||
if (ret != RIG_OK)
|
}
|
||||||
return ret;
|
|
||||||
|
|
||||||
|
static int thd72_set_vfo(RIG *rig, vfo_t vfo)
|
||||||
|
{
|
||||||
|
const char *cmd;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
switch (vfo) {
|
||||||
|
case RIG_VFO_A:
|
||||||
|
case RIG_VFO_VFO:
|
||||||
|
case RIG_VFO_MAIN:
|
||||||
|
cmd = "BC 0";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_VFO_B:
|
||||||
|
cmd = "BC 1";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %d\n", __func__, vfo);
|
||||||
|
return -RIG_ENTARGET;
|
||||||
|
}
|
||||||
|
return kenwood_simple_transaction(rig, cmd, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_get_vfo(RIG *rig, vfo_t *vfo)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char buf[10], vfoc;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = kenwood_transaction(rig, "BC", buf, sizeof (buf));
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
size_t length = strlen (buf);
|
||||||
|
if (length == 4) {
|
||||||
|
vfoc = buf[3];
|
||||||
|
} else {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer length '%c'\n", __func__, length);
|
||||||
|
return -RIG_EPROTO;
|
||||||
|
}
|
||||||
|
switch (vfoc) {
|
||||||
|
case '0': *vfo = RIG_VFO_A; break;
|
||||||
|
case '1': *vfo = RIG_VFO_B; break;
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %d\n", __func__, vfo);
|
||||||
|
return -RIG_EVFO;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_vfoc(RIG *rig, vfo_t vfo, char *vfoc)
|
||||||
|
{
|
||||||
|
vfo = (vfo == RIG_VFO_CURR) ? rig->state.current_vfo : vfo;
|
||||||
|
switch (vfo) {
|
||||||
|
case RIG_VFO_A: *vfoc = '0'; break;
|
||||||
|
case RIG_VFO_B: *vfoc = '1'; break;
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %d\n", __func__, vfo);
|
||||||
|
return -RIG_ENTARGET;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_get_freq_info(RIG *rig, vfo_t vfo, char *buf)
|
||||||
|
{
|
||||||
|
int retval, length;
|
||||||
|
char vfoc, cmd[8];
|
||||||
|
|
||||||
|
retval = thd72_vfoc(rig, vfo, &vfoc);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
sprintf(cmd, "FO %c", vfoc);
|
||||||
|
retval = kenwood_transaction(rig, cmd, buf, 53);
|
||||||
|
length = strlen(buf);
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: length=%d\n", __func__, length);
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char buf[64], fbuf[11];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_get_freq_info(rig, vfo, buf);
|
||||||
|
if (retval == RIG_OK) {
|
||||||
|
sprintf(fbuf, "%010ld", (int64_t)freq);
|
||||||
|
memcpy(buf+5, fbuf, 10);
|
||||||
|
retval = kenwood_simple_transaction(rig, buf, 52);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_get_freq_info(rig, vfo, buf);
|
||||||
|
if (retval == RIG_OK)
|
||||||
|
sscanf(buf+5, "%"SCNfreq, freq);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char modec, buf[64];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_get_freq_info(rig, vfo, buf);
|
||||||
|
if (retval == RIG_OK) {
|
||||||
|
switch (mode) {
|
||||||
|
case RIG_MODE_WFM: modec = '0'; break;
|
||||||
|
case RIG_MODE_FM: modec = '1'; break;
|
||||||
|
case RIG_MODE_AM: modec = '2'; break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
buf[51] = modec;
|
||||||
|
retval = kenwood_simple_transaction(rig, buf, 52);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char modec, buf[64];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_get_freq_info(rig, vfo, buf);
|
||||||
|
if (retval == RIG_OK) {
|
||||||
|
modec = buf[51];
|
||||||
|
if (modec >= '0' && modec <= '2') {
|
||||||
|
*mode = thd72_mode_table[modec - '0'];
|
||||||
|
*width = thd72_width_table[modec - '0'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_set_rptr_shft(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char shftc, buf[64];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_get_freq_info(rig, vfo, buf);
|
||||||
|
if (retval == RIG_OK) {
|
||||||
|
switch (rptr_shift) {
|
||||||
|
case RIG_RPT_SHIFT_NONE: shftc = '0'; break;
|
||||||
|
case RIG_RPT_SHIFT_PLUS: shftc = '1'; break;
|
||||||
|
case RIG_RPT_SHIFT_MINUS: shftc = '1'; break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
buf[18] = shftc;
|
||||||
|
retval = kenwood_simple_transaction(rig, buf, 52);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_get_rptr_shft(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char shftc, buf[64];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_get_freq_info(rig, vfo, buf);
|
||||||
|
if (retval == RIG_OK) {
|
||||||
|
shftc = buf[18];
|
||||||
|
if (shftc >= '0' && shftc <= '2') {
|
||||||
|
*rptr_shift = thd72_rshf_table[shftc - '0'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int thd72_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char boff[9], buf[64];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_get_freq_info(rig, vfo, buf);
|
||||||
|
if (retval == RIG_OK) {
|
||||||
|
sprintf(boff, "%08ld", offs);
|
||||||
|
memcpy(buf+42, boff, 8);
|
||||||
|
retval = kenwood_simple_transaction(rig, buf, 52);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_get_freq_info(rig, vfo, buf);
|
||||||
|
if (retval == RIG_OK)
|
||||||
|
sscanf(buf+42, "%ld", offs);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
retval = -RIG_EINVAL; /** TEMP **/
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
int tinx;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_get_freq_info(rig, vfo, buf);
|
||||||
|
if (retval == RIG_OK) {
|
||||||
|
if (buf[22] == '0') /* no tone */
|
||||||
|
*tone = 0;
|
||||||
|
else {
|
||||||
|
sscanf(buf+30, "%d", &tinx);
|
||||||
|
if (tinx >= 0 && tinx <= 41)
|
||||||
|
*tone = kenwood42_ctcss_list[tinx];
|
||||||
|
else
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_get_menu_info(RIG *rig, char *buf)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = kenwood_transaction(rig, "MU", buf, 41);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
if (strlen(buf) != 40)
|
||||||
|
return -RIG_ERJCTED;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char vfoc, lvlc, cmd[10], buf[48];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_vfoc(rig, vfo, &vfoc);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
switch (level) {
|
||||||
|
case RIG_LEVEL_RFPOWER:
|
||||||
|
if (val.f <= 0.01) lvlc = '2';
|
||||||
|
else if (val.f <= 0.10) lvlc = '1';
|
||||||
|
else lvlc = '0';
|
||||||
|
sprintf(cmd, "PC %c,%c", vfoc, lvlc);
|
||||||
|
return kenwood_simple_transaction(rig, cmd, 6);
|
||||||
|
case RIG_LEVEL_VOXGAIN:
|
||||||
|
retval = thd72_get_menu_info(rig, buf);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
buf[19] = '0' + (int)(val.f*10.0 - 0.5);
|
||||||
|
return kenwood_simple_transaction(rig, buf, 40);
|
||||||
|
case RIG_LEVEL_VOXDELAY:
|
||||||
|
retval = thd72_get_menu_info(rig, buf);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %d\n", __func__, level);
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
||||||
|
{
|
||||||
|
int retval, v, l;
|
||||||
|
char vfoc, cmd[10], buf[48];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||||
|
|
||||||
|
retval = thd72_vfoc(rig, vfo, &vfoc);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
switch (level) {
|
||||||
|
case RIG_LEVEL_RFPOWER:
|
||||||
|
sprintf(cmd, "PC %c", vfoc);
|
||||||
|
retval = kenwood_transaction(rig, cmd, buf, sizeof (buf));
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
retval = sscanf(buf, "PC %d,%d", &v, &l);
|
||||||
|
if (retval != 2 || l < 0 || l > 3) {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf);
|
||||||
|
return -RIG_ERJCTED;
|
||||||
|
}
|
||||||
|
switch (l) {
|
||||||
|
case 0: val->f = 1.00; break; /* 5.0 W */
|
||||||
|
case 1: val->f = 0.10; break; /* 500 mW */
|
||||||
|
case 2: val->f = 0.01; break; /* 50 mW */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RIG_LEVEL_VOXGAIN:
|
||||||
|
retval = thd72_get_menu_info(rig, buf);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
/* FIXME - if VOX is off, what do we return */
|
||||||
|
vfoc = buf[19];
|
||||||
|
if (vfoc >= '0' && vfoc <= '9')
|
||||||
|
val->f = (vfoc - '0') / 9.0;
|
||||||
|
else {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf);
|
||||||
|
return -RIG_ERJCTED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RIG_LEVEL_VOXDELAY:
|
||||||
|
retval = thd72_get_menu_info(rig, buf);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
/* FIXME - if VOX is off, what do we return */
|
||||||
|
vfoc = buf[21];
|
||||||
|
if (vfoc >= '0' && vfoc <= '7')
|
||||||
|
val->i = thd72voxdelay[vfoc-'0'];
|
||||||
|
else {
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf);
|
||||||
|
return -RIG_ERJCTED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %d\n", __func__, level);
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
|
||||||
|
{
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thd72_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char vfoc, buf[48];
|
||||||
|
|
||||||
|
switch (func) {
|
||||||
|
case RIG_FUNC_AIP:
|
||||||
|
retval = thd72_vfoc(rig, vfo, &vfoc);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
retval = thd72_get_menu_info(rig, buf);
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
return retval;
|
||||||
|
if (vfoc == '0') vfoc = buf[13]; /* VHF AIP */
|
||||||
|
else vfoc = buf[15]; /* UHF AIP */
|
||||||
|
*status = vfoc - '0';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,3 +641,120 @@ int thd72_get_chan_all_cb (RIG * rig, chan_cb_t chan_cb, rig_ptr_t arg)
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* th-d72a rig capabilities.
|
||||||
|
*/
|
||||||
|
const struct rig_caps thd72a_caps = {
|
||||||
|
.rig_model = RIG_MODEL_THD72A,
|
||||||
|
.model_name = "TH-D72A",
|
||||||
|
.mfg_name = "Kenwood",
|
||||||
|
.version = TH_VER ".1",
|
||||||
|
.copyright = "LGPL",
|
||||||
|
.status = RIG_STATUS_ALPHA,
|
||||||
|
.rig_type = RIG_TYPE_HANDHELD|RIG_FLAG_APRS|RIG_FLAG_TNC|RIG_FLAG_DXCLUSTER,
|
||||||
|
.ptt_type = RIG_PTT_RIG,
|
||||||
|
.dcd_type = RIG_DCD_RIG,
|
||||||
|
.port_type = RIG_PORT_SERIAL,
|
||||||
|
.serial_rate_min = 9600,
|
||||||
|
.serial_rate_max = 9600,
|
||||||
|
.serial_data_bits = 8,
|
||||||
|
.serial_stop_bits = 1,
|
||||||
|
.serial_parity = RIG_PARITY_NONE,
|
||||||
|
.serial_handshake = RIG_HANDSHAKE_XONXOFF,
|
||||||
|
.write_delay = 0,
|
||||||
|
.post_write_delay = 0,
|
||||||
|
.timeout = 250,
|
||||||
|
.retry = 3,
|
||||||
|
|
||||||
|
.has_get_func = THD72_FUNC_ALL,
|
||||||
|
.has_set_func = THD72_FUNC_ALL,
|
||||||
|
.has_get_level = THD72_LEVEL_ALL,
|
||||||
|
.has_set_level = RIG_LEVEL_SET(THD72_LEVEL_ALL),
|
||||||
|
.has_get_parm = THD72_PARMS,
|
||||||
|
.has_set_parm = THD72_PARMS, /* FIXME: parms */
|
||||||
|
.level_gran = {
|
||||||
|
[LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 5 } },
|
||||||
|
[LVL_SQL] = { .min = { .i = 0 }, .max = { .i = 5 } },
|
||||||
|
[LVL_RFPOWER] = { .min = { .i = 2 }, .max = { .i = 0 } },
|
||||||
|
},
|
||||||
|
.parm_gran = {},
|
||||||
|
.ctcss_list = kenwood38_ctcss_list,
|
||||||
|
.dcs_list = NULL,
|
||||||
|
.preamp = { RIG_DBLST_END, },
|
||||||
|
.attenuator = { RIG_DBLST_END, },
|
||||||
|
.max_rit = Hz(0),
|
||||||
|
.max_xit = Hz(0),
|
||||||
|
.max_ifshift = Hz(0),
|
||||||
|
.vfo_ops = THD72_VFO_OP,
|
||||||
|
.targetable_vfo = RIG_TARGETABLE_FREQ,
|
||||||
|
.transceive = RIG_TRN_RIG,
|
||||||
|
.bank_qty = 0,
|
||||||
|
.chan_desc_sz = 6, /* TBC */
|
||||||
|
|
||||||
|
.chan_list = {
|
||||||
|
{ 0, 999, RIG_MTYPE_MEM , {TH_CHANNEL_CAPS}}, /* TBC MEM */
|
||||||
|
RIG_CHAN_END,
|
||||||
|
},
|
||||||
|
|
||||||
|
.rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */
|
||||||
|
.tx_range_list1 = { RIG_FRNG_END, },
|
||||||
|
.rx_range_list2 = {
|
||||||
|
{MHz(118),MHz(174),THD72_MODES,-1,-1,THD72_VFO},
|
||||||
|
{MHz(320),MHz(524),THD72_MODES,-1,-1,THD72_VFO},
|
||||||
|
RIG_FRNG_END,
|
||||||
|
}, /* rx range */
|
||||||
|
.tx_range_list2 = {
|
||||||
|
{MHz(144),MHz(148),THD72_MODES_TX,W(0.05),W(5),THD72_VFO},
|
||||||
|
{MHz(430),MHz(440),THD72_MODES_TX,W(0.05),W(5),THD72_VFO},
|
||||||
|
RIG_FRNG_END,
|
||||||
|
}, /* tx range */
|
||||||
|
|
||||||
|
.tuning_steps = {
|
||||||
|
{THD72_MODES,kHz(5)},
|
||||||
|
{THD72_MODES,kHz(6.25)},
|
||||||
|
/* kHz(8.33) ?? */
|
||||||
|
{THD72_MODES,kHz(10)},
|
||||||
|
{THD72_MODES,kHz(12.5)},
|
||||||
|
{THD72_MODES,kHz(15)},
|
||||||
|
{THD72_MODES,kHz(20)},
|
||||||
|
{THD72_MODES,kHz(25)},
|
||||||
|
{THD72_MODES,kHz(30)},
|
||||||
|
{THD72_MODES,kHz(50)},
|
||||||
|
{THD72_MODES,kHz(100)},
|
||||||
|
RIG_TS_END,
|
||||||
|
},
|
||||||
|
/* mode/filter list, remember: order matters! */
|
||||||
|
.filters = {
|
||||||
|
{RIG_MODE_FM, kHz(14)},
|
||||||
|
{RIG_MODE_AM, kHz(9)},
|
||||||
|
RIG_FLT_END,
|
||||||
|
},
|
||||||
|
.priv = (void *)&thd72_priv_caps,
|
||||||
|
|
||||||
|
.rig_init = kenwood_init,
|
||||||
|
.rig_cleanup = kenwood_cleanup,
|
||||||
|
.rig_open = thd72_open,
|
||||||
|
.set_freq = thd72_set_freq,
|
||||||
|
.get_freq = thd72_get_freq,
|
||||||
|
.set_mode = thd72_set_mode,
|
||||||
|
.get_mode = thd72_get_mode,
|
||||||
|
.set_vfo = thd72_set_vfo,
|
||||||
|
.get_vfo = thd72_get_vfo,
|
||||||
|
.set_rptr_shift = thd72_set_rptr_shft,
|
||||||
|
.get_rptr_shift = thd72_get_rptr_shft,
|
||||||
|
.set_rptr_offs = thd72_set_rptr_offs,
|
||||||
|
.get_rptr_offs = thd72_get_rptr_offs,
|
||||||
|
.set_ctcss_tone = thd72_set_ctcss_tone,
|
||||||
|
.get_ctcss_tone = thd72_get_ctcss_tone,
|
||||||
|
// set/get dcs_code
|
||||||
|
//.set_ctcss_sql = th_set_ctcss_sql,
|
||||||
|
//.get_ctcss_sql = th_get_ctcss_sql,
|
||||||
|
.set_level = thd72_set_level,
|
||||||
|
.get_level = thd72_get_level,
|
||||||
|
.set_func = thd72_set_func,
|
||||||
|
.get_func = thd72_get_func,
|
||||||
|
.get_chan_all_cb = thd72_get_chan_all_cb,
|
||||||
|
|
||||||
|
.get_info = th_get_info,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
Ładowanie…
Reference in New Issue