kopia lustrzana https://github.com/Hamlib/Hamlib
PowerSDR rig now recognizes 10 modes 0-11 but not SPEC or DRM yet
Bandwidth returns now accurately reflect bandwith on Thetis (tested) Setting bandwidth for PKTUSB/PKTLSB uses 150Hz for lo and hi=width For example PKTUSB/6000 will set lo=150 and hi=6000 https://github.com/Hamlib/Hamlib/issues/344pull/351/head
rodzic
b135aa3da6
commit
614ffe8dab
|
@ -62,12 +62,34 @@ static rmode_t flex_mode_table[KENWOOD_MODE_TABLE_MAX] =
|
||||||
[9] = RIG_MODE_PKTUSB
|
[9] = RIG_MODE_PKTUSB
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static rmode_t powersdr_mode_table[KENWOOD_MODE_TABLE_MAX] =
|
||||||
|
{
|
||||||
|
[0] = RIG_MODE_LSB,
|
||||||
|
[1] = RIG_MODE_USB,
|
||||||
|
[2] = RIG_MODE_DSB,
|
||||||
|
[3] = RIG_MODE_CWR,
|
||||||
|
[4] = RIG_MODE_CW,
|
||||||
|
[5] = RIG_MODE_FM,
|
||||||
|
[6] = RIG_MODE_AM,
|
||||||
|
[7] = RIG_MODE_PKTUSB,
|
||||||
|
[8] = RIG_MODE_NONE,
|
||||||
|
[8] = RIG_MODE_PKTLSB,
|
||||||
|
[10] = RIG_MODE_SAM,
|
||||||
|
[11] = RIG_MODE_NONE
|
||||||
|
};
|
||||||
|
|
||||||
static struct kenwood_priv_caps f6k_priv_caps =
|
static struct kenwood_priv_caps f6k_priv_caps =
|
||||||
{
|
{
|
||||||
.cmdtrm = EOM_KEN,
|
.cmdtrm = EOM_KEN,
|
||||||
.mode_table = flex_mode_table,
|
.mode_table = flex_mode_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct kenwood_priv_caps powersdr_priv_caps =
|
||||||
|
{
|
||||||
|
.cmdtrm = EOM_KEN,
|
||||||
|
.mode_table = powersdr_mode_table,
|
||||||
|
};
|
||||||
|
|
||||||
#define DSP_BW_NUM 8
|
#define DSP_BW_NUM 8
|
||||||
|
|
||||||
static int dsp_bw_ssb[DSP_BW_NUM] =
|
static int dsp_bw_ssb[DSP_BW_NUM] =
|
||||||
|
@ -90,6 +112,37 @@ static int dsp_bw_dig[DSP_BW_NUM] =
|
||||||
3000, 2000, 1500, 1000, 600, 300, 150, 100
|
3000, 2000, 1500, 1000, 600, 300, 150, 100
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// PowerSDR settings
|
||||||
|
#define DSP_BW_NUM_POWERSDR 12
|
||||||
|
|
||||||
|
static int dsp_bw_ssb_powersdr[DSP_BW_NUM_POWERSDR] =
|
||||||
|
{
|
||||||
|
5000, 4400, 3800, 3300, 2900, 2700, 2400, 2100, 1800, 1000, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static int dsp_bw_am_powersdr[DSP_BW_NUM_POWERSDR] =
|
||||||
|
{
|
||||||
|
16000, 12000, 10000, 8000, 6600, 5200, 4000, 3100, 2900, 2400, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static int dsp_bw_cw_powersdr[DSP_BW_NUM_POWERSDR] =
|
||||||
|
{
|
||||||
|
1000, 800, 600, 500, 400, 250, 150, 100, 50, 25, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static int dsp_bw_dig_powersdr[DSP_BW_NUM_POWERSDR] =
|
||||||
|
{
|
||||||
|
3000, 2500, 2000, 1500, 1000, 800, 600, 300, 150, 75, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0 // not used yet
|
||||||
|
static int dsp_bw_sam_powersdr[DSP_BW_NUM_POWERSDR] =
|
||||||
|
{
|
||||||
|
20000, 18000, 16000, 12000, 10000, 9000, 8000, 7000, 6000, 5000, 0, 0
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Private helper functions */
|
/* Private helper functions */
|
||||||
|
|
||||||
static int flex6k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
static int flex6k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
||||||
|
@ -123,7 +176,8 @@ static int flex6k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Flex CAT interface does not support FW for reading filter width,
|
* The Flex CAT interface does not support FW for reading filter width,
|
||||||
* so use the ZZFI or ZZFJ command
|
* so use the ZZFI
|
||||||
|
* Have to determine what to do with receiver#2 if anybody ever asks
|
||||||
*/
|
*/
|
||||||
switch (vfo)
|
switch (vfo)
|
||||||
{
|
{
|
||||||
|
@ -150,13 +204,14 @@ static int flex6k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
||||||
if (index >= DSP_BW_NUM)
|
if (index >= DSP_BW_NUM)
|
||||||
{
|
{
|
||||||
rig_debug(RIG_DEBUG_ERR,
|
rig_debug(RIG_DEBUG_ERR,
|
||||||
"flex6k_get_mode: unexpected ZZF[IJ] answer, index=%d\n", index);
|
"%s: unexpected ZZF[IJ] answer, index=%d\n", __func__, index);
|
||||||
return -RIG_ERJCTED;
|
return -RIG_ERJCTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (*mode)
|
switch (*mode)
|
||||||
{
|
{
|
||||||
case RIG_MODE_AM:
|
case RIG_MODE_AM:
|
||||||
|
case RIG_MODE_DSB:
|
||||||
*width = dsp_bw_am[index];
|
*width = dsp_bw_am[index];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -187,6 +242,75 @@ static int flex6k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int powersdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode,
|
||||||
|
pbwidth_t *width)
|
||||||
|
{
|
||||||
|
struct kenwood_priv_caps *caps = kenwood_caps(rig);
|
||||||
|
char modebuf[10];
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
|
|
||||||
|
if (!mode || !width)
|
||||||
|
{
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = kenwood_safe_transaction(rig, "ZZMD", modebuf, 10, 6);
|
||||||
|
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
{
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
*mode = kenwood2rmode(atoi(&modebuf[4]), caps->mode_table);
|
||||||
|
|
||||||
|
if ((vfo == RIG_VFO_VFO) || (vfo == RIG_VFO_CURR))
|
||||||
|
{
|
||||||
|
vfo = rig->state.current_vfo;
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: setting VFO to current\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Flex CAT interface does not support FW for reading filter width,
|
||||||
|
* so use the ZZFI or ZZFJ command
|
||||||
|
*/
|
||||||
|
switch (vfo)
|
||||||
|
{
|
||||||
|
int lo, hi;
|
||||||
|
|
||||||
|
case RIG_VFO_A:
|
||||||
|
case RIG_VFO_B:
|
||||||
|
retval = kenwood_safe_transaction(rig, "ZZFL", modebuf, 10, 9);
|
||||||
|
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
{
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
lo = atoi(&modebuf[4]);
|
||||||
|
retval = kenwood_safe_transaction(rig, "ZZFH", modebuf, 10, 9);
|
||||||
|
|
||||||
|
if (retval != RIG_OK)
|
||||||
|
{
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
hi = atoi(&modebuf[4]);
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: lo=%d, hi=%d\n", __func__, lo, hi);
|
||||||
|
*width = hi - lo;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo));
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Private helper functions */
|
||||||
|
|
||||||
static int flex6k_find_width(rmode_t mode, pbwidth_t width, int *ridx)
|
static int flex6k_find_width(rmode_t mode, pbwidth_t width, int *ridx)
|
||||||
{
|
{
|
||||||
int *w_a; // Width array, these are all ordered in descending order!
|
int *w_a; // Width array, these are all ordered in descending order!
|
||||||
|
@ -238,6 +362,58 @@ static int flex6k_find_width(rmode_t mode, pbwidth_t width, int *ridx)
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int powersdr_find_width(rmode_t mode, pbwidth_t width, int *ridx)
|
||||||
|
{
|
||||||
|
int *w_a; // Width array, these are all ordered in descending order!
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case RIG_MODE_AM:
|
||||||
|
w_a = dsp_bw_am_powersdr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_MODE_CW:
|
||||||
|
case RIG_MODE_CWR:
|
||||||
|
w_a = dsp_bw_cw_powersdr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_MODE_USB:
|
||||||
|
case RIG_MODE_LSB:
|
||||||
|
w_a = dsp_bw_ssb_powersdr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//case RIG_MODE_FM:
|
||||||
|
//*width = 3000; /* not supported yet, needs followup */
|
||||||
|
//break;
|
||||||
|
case RIG_MODE_PKTLSB:
|
||||||
|
case RIG_MODE_PKTUSB:
|
||||||
|
w_a = dsp_bw_dig_powersdr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__,
|
||||||
|
rig_strrmode(mode));
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the first smaller or equal possibility
|
||||||
|
while ((idx < DSP_BW_NUM) && (w_a[idx] > width))
|
||||||
|
{
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx >= DSP_BW_NUM)
|
||||||
|
{
|
||||||
|
idx = DSP_BW_NUM - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ridx = idx;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int flex6k_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
static int flex6k_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
{
|
{
|
||||||
struct kenwood_priv_caps *caps = kenwood_caps(rig);
|
struct kenwood_priv_caps *caps = kenwood_caps(rig);
|
||||||
|
@ -308,6 +484,87 @@ static int flex6k_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
|
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int powersdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
|
{
|
||||||
|
struct kenwood_priv_caps *caps = kenwood_caps(rig);
|
||||||
|
char buf[64];
|
||||||
|
char kmode;
|
||||||
|
int idx;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called mode=%s, width=%d\n", __func__,
|
||||||
|
rig_strrmode(mode), (int)width);
|
||||||
|
|
||||||
|
kmode = rmode2kenwood(mode, caps->mode_table);
|
||||||
|
|
||||||
|
if (kmode < 0)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n",
|
||||||
|
__func__, rig_strrmode(mode));
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buf, "ZZMD%02d", kmode);
|
||||||
|
err = kenwood_transaction(rig, buf, NULL, 0);
|
||||||
|
|
||||||
|
if (err != RIG_OK)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vfo == RIG_VFO_VFO) || (vfo == RIG_VFO_CURR))
|
||||||
|
{
|
||||||
|
vfo = rig->state.current_vfo;
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: setting VFO to current\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RIG_PASSBAND_NOCHANGE == width) { return err; }
|
||||||
|
|
||||||
|
err = powersdr_find_width(mode, width, &idx);
|
||||||
|
|
||||||
|
if (err != RIG_OK)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Flex CAT interface does not support FW for reading filter width,
|
||||||
|
* so use the ZZFI or ZZFJ command
|
||||||
|
*/
|
||||||
|
switch (vfo)
|
||||||
|
{
|
||||||
|
case RIG_VFO_B:
|
||||||
|
case RIG_VFO_A:
|
||||||
|
if ((mode == RIG_MODE_PKTUSB || mode == RIG_MODE_PKTLSB) && width > 3000)
|
||||||
|
{
|
||||||
|
// 150Hz on the low end should be enough
|
||||||
|
// Set high to the width requested
|
||||||
|
sprintf(buf, "ZZFL00150;ZZFH%05d;", (int)width);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(buf, "ZZFI%02d;", idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// what do we do about RX2 ??
|
||||||
|
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo));
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = kenwood_transaction(rig, buf, NULL, 0);
|
||||||
|
|
||||||
|
if (err != RIG_OK)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* flex6k_get_ptt
|
* flex6k_get_ptt
|
||||||
*/
|
*/
|
||||||
|
@ -504,9 +761,9 @@ const struct rig_caps powersdr_caps =
|
||||||
RIG_MODEL(RIG_MODEL_POWERSDR),
|
RIG_MODEL(RIG_MODEL_POWERSDR),
|
||||||
.model_name = "PowerSDR",
|
.model_name = "PowerSDR",
|
||||||
.mfg_name = "FlexRadio",
|
.mfg_name = "FlexRadio",
|
||||||
.version = "20200528.0",
|
.version = "20200716.0",
|
||||||
.copyright = "LGPL",
|
.copyright = "LGPL",
|
||||||
.status = RIG_STATUS_BETA,
|
.status = RIG_STATUS_STABLE,
|
||||||
.rig_type = RIG_TYPE_TRANSCEIVER,
|
.rig_type = RIG_TYPE_TRANSCEIVER,
|
||||||
.ptt_type = RIG_PTT_RIG,
|
.ptt_type = RIG_PTT_RIG,
|
||||||
.dcd_type = RIG_DCD_NONE,
|
.dcd_type = RIG_DCD_NONE,
|
||||||
|
@ -518,12 +775,12 @@ const struct rig_caps powersdr_caps =
|
||||||
.serial_parity = RIG_PARITY_NONE,
|
.serial_parity = RIG_PARITY_NONE,
|
||||||
.serial_handshake = RIG_HANDSHAKE_NONE,
|
.serial_handshake = RIG_HANDSHAKE_NONE,
|
||||||
.write_delay = 0,
|
.write_delay = 0,
|
||||||
.post_write_delay = 0, /* ms */
|
.post_write_delay = 20,
|
||||||
// The combination of timeout and retry is important
|
// The combination of timeout and retry is important
|
||||||
// We need at least 3 seconds to do profile switches
|
// We need at least 3 seconds to do profile switches
|
||||||
// Hitting the timeout is OK as long as we retry
|
// Hitting the timeout is OK as long as we retry
|
||||||
// Previous note showed FA/FB may take up to 500ms on band change
|
// Previous note showed FA/FB may take up to 500ms on band change
|
||||||
.timeout = 250,
|
.timeout = 800, // some band transitions can take 600ms
|
||||||
.retry = 3,
|
.retry = 3,
|
||||||
|
|
||||||
.has_get_func = RIG_FUNC_NONE, /* has VOX but not implemented here */
|
.has_get_func = RIG_FUNC_NONE, /* has VOX but not implemented here */
|
||||||
|
@ -536,7 +793,6 @@ const struct rig_caps powersdr_caps =
|
||||||
.parm_gran = {},
|
.parm_gran = {},
|
||||||
//.extlevels = elecraft_ext_levels,
|
//.extlevels = elecraft_ext_levels,
|
||||||
//.extparms = kenwood_cfg_params,
|
//.extparms = kenwood_cfg_params,
|
||||||
.post_write_delay = 20,
|
|
||||||
.preamp = { RIG_DBLST_END, },
|
.preamp = { RIG_DBLST_END, },
|
||||||
.attenuator = { RIG_DBLST_END, },
|
.attenuator = { RIG_DBLST_END, },
|
||||||
.max_rit = Hz(0),
|
.max_rit = Hz(0),
|
||||||
|
@ -604,7 +860,7 @@ const struct rig_caps powersdr_caps =
|
||||||
{RIG_MODE_FM, kHz(13)}, /* TBC */
|
{RIG_MODE_FM, kHz(13)}, /* TBC */
|
||||||
RIG_FLT_END,
|
RIG_FLT_END,
|
||||||
},
|
},
|
||||||
.priv = (void *)& f6k_priv_caps,
|
.priv = (void *)& powersdr_priv_caps,
|
||||||
|
|
||||||
.rig_init = kenwood_init,
|
.rig_init = kenwood_init,
|
||||||
.rig_cleanup = kenwood_cleanup,
|
.rig_cleanup = kenwood_cleanup,
|
||||||
|
@ -612,8 +868,8 @@ const struct rig_caps powersdr_caps =
|
||||||
.rig_close = kenwood_close,
|
.rig_close = kenwood_close,
|
||||||
.set_freq = kenwood_set_freq,
|
.set_freq = kenwood_set_freq,
|
||||||
.get_freq = kenwood_get_freq,
|
.get_freq = kenwood_get_freq,
|
||||||
.set_mode = flex6k_set_mode,
|
.set_mode = powersdr_set_mode,
|
||||||
.get_mode = flex6k_get_mode,
|
.get_mode = powersdr_get_mode,
|
||||||
.set_vfo = kenwood_set_vfo,
|
.set_vfo = kenwood_set_vfo,
|
||||||
.get_vfo = kenwood_get_vfo_if,
|
.get_vfo = kenwood_get_vfo_if,
|
||||||
.set_split_vfo = kenwood_set_split_vfo,
|
.set_split_vfo = kenwood_set_split_vfo,
|
||||||
|
|
Ładowanie…
Reference in New Issue