kopia lustrzana https://github.com/Hamlib/Hamlib
Implement ext level for Yaesu roofing filter. Move question mark response interpretation mode to private state.
rodzic
ec60ffface
commit
20d00263bc
|
@ -39,6 +39,34 @@
|
|||
|
||||
cal_table_float_t yaesu_ftdx101d_swr_cal = FTDX101D_SWR_CAL;
|
||||
|
||||
const struct newcat_priv_caps ftdx101d_priv_caps =
|
||||
{
|
||||
.roofing_filter_count = 5,
|
||||
.roofing_filters =
|
||||
{
|
||||
// The index must match ext level combo index
|
||||
{ .index = 0, .set_value = '1', .get_value = '6', .width = 12000, .optional = 0 },
|
||||
{ .index = 1, .set_value = '2', .get_value = '7', .width = 3000, .optional = 0 },
|
||||
{ .index = 2, .set_value = '3', .get_value = '8', .width = 1200, .optional = 1 },
|
||||
{ .index = 3, .set_value = '4', .get_value = '9', .width = 600, .optional = 0 },
|
||||
{ .index = 4, .set_value = '5', .get_value = 'A', .width = 300, .optional = 1 },
|
||||
}
|
||||
};
|
||||
|
||||
const struct confparams ftdx101d_ext_levels[] =
|
||||
{
|
||||
{
|
||||
TOK_ROOFING_FILTER,
|
||||
"ROOFINGFILTER",
|
||||
"Roofing filter",
|
||||
"Roofing filter",
|
||||
NULL,
|
||||
RIG_CONF_COMBO,
|
||||
{ .c = { .combostr = { "12 kHz", "3 kHz", "1.2 kHz (optional)", "600 Hz", "300 Hz (optional)", NULL } } }
|
||||
},
|
||||
{ RIG_CONF_END, NULL, }
|
||||
};
|
||||
|
||||
const struct rig_caps ftdx101d_caps =
|
||||
{
|
||||
RIG_MODEL(RIG_MODEL_FTDX101D),
|
||||
|
@ -152,7 +180,9 @@ const struct rig_caps ftdx101d_caps =
|
|||
RIG_FLT_END,
|
||||
},
|
||||
|
||||
.priv = NULL,
|
||||
.extlevels = ftdx101d_ext_levels,
|
||||
|
||||
.priv = &ftdx101d_priv_caps,
|
||||
|
||||
.rig_init = newcat_init,
|
||||
.rig_cleanup = newcat_cleanup,
|
||||
|
|
|
@ -379,6 +379,9 @@ static int newcat_get_faststep(RIG *rig, ncboolean *fast_step);
|
|||
static int newcat_get_rigid(RIG *rig);
|
||||
static int newcat_get_vfo_mode(RIG *rig, vfo_t *vfo_mode);
|
||||
static int newcat_vfomem_toggle(RIG *rig);
|
||||
static int set_roofing_filter(RIG *rig, vfo_t vfo, int index);
|
||||
static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width);
|
||||
static int get_roofing_filter(RIG *rig, vfo_t vfo, struct newcat_roofing_filter **roofing_filter);
|
||||
static ncboolean newcat_valid_command(RIG *rig, char const *const command);
|
||||
|
||||
/*
|
||||
|
@ -476,6 +479,8 @@ int newcat_open(RIG *rig)
|
|||
priv->poweron = 1;
|
||||
}
|
||||
|
||||
priv->question_mark_response_means_rejected = 0;
|
||||
|
||||
/* get current AI state so it can be restored */
|
||||
priv->trn_state = -1;
|
||||
|
||||
|
@ -4488,17 +4493,44 @@ int newcat_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val)
|
|||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
switch (token)
|
||||
{
|
||||
case TOK_ROOFING_FILTER:
|
||||
return set_roofing_filter(rig, vfo, val.i);
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %s\n", __func__, rig_strlevel(token));
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int newcat_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *val)
|
||||
{
|
||||
int retval;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
switch (token)
|
||||
{
|
||||
case TOK_ROOFING_FILTER:
|
||||
{
|
||||
struct newcat_roofing_filter *roofing_filter;
|
||||
retval = get_roofing_filter(rig, vfo, &roofing_filter);
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
val->i = roofing_filter->index;
|
||||
}
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %s\n", __func__, rig_strlevel(token));
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int newcat_set_ext_parm(RIG *rig, token_t token, value_t val)
|
||||
{
|
||||
|
@ -4636,7 +4668,9 @@ int newcat_set_mem(RIG *rig, vfo_t vfo, int ch)
|
|||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
|
||||
|
||||
err = newcat_set_cmd_ext(rig, 1);
|
||||
priv->question_mark_response_means_rejected = 1;
|
||||
err = newcat_set_cmd(rig);
|
||||
priv->question_mark_response_means_rejected = 0;
|
||||
|
||||
if (err != RIG_OK)
|
||||
{
|
||||
|
@ -4999,7 +5033,9 @@ int newcat_set_channel(RIG *rig, const channel_t *chan)
|
|||
rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str);
|
||||
|
||||
/* Set Memory Channel */
|
||||
err = newcat_set_cmd_ext(rig, 1);
|
||||
priv->question_mark_response_means_rejected = 1;
|
||||
err = newcat_set_cmd(rig);
|
||||
priv->question_mark_response_means_rejected = 0;
|
||||
|
||||
if (err != RIG_OK)
|
||||
{
|
||||
|
@ -5062,7 +5098,10 @@ int newcat_get_channel(RIG *rig, channel_t *chan, int read_only)
|
|||
|
||||
|
||||
/* Get Memory Channel */
|
||||
if (RIG_OK != (err = newcat_get_cmd_ext(rig, 1)))
|
||||
priv->question_mark_response_means_rejected = 1;
|
||||
err = newcat_get_cmd(rig);
|
||||
priv->question_mark_response_means_rejected = 0;
|
||||
if (RIG_OK != err)
|
||||
{
|
||||
if (-RIG_ERJCTED == err)
|
||||
{
|
||||
|
@ -6081,8 +6120,6 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
|||
} // end is_ft1200
|
||||
else if (is_ft101)
|
||||
{
|
||||
int roof_width;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case RIG_MODE_PKTUSB:
|
||||
|
@ -6141,21 +6178,10 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
|||
else { w = 23; } // 4000Hz
|
||||
} // end switch(mode)
|
||||
|
||||
// set roofing filter to allow for requested bandwidth
|
||||
// widths of 3 and 5 are optional so won't do them
|
||||
if (width <= 600) { roof_width = 4; }
|
||||
else if (width <= 3000) { roof_width = 2; }
|
||||
else { roof_width = 1; }
|
||||
|
||||
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%1d%c", main_sub_vfo,
|
||||
roof_width,
|
||||
cat_term);
|
||||
|
||||
if (RIG_OK != (err = newcat_set_cmd(rig)))
|
||||
if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
} // end is_ft101
|
||||
else
|
||||
{
|
||||
|
@ -6220,31 +6246,137 @@ int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
|||
return newcat_set_cmd(rig);
|
||||
}
|
||||
|
||||
static char get_roofing_filter(RIG *rig, vfo_t vfo)
|
||||
static int set_roofing_filter(RIG *rig, vfo_t vfo, int index)
|
||||
{
|
||||
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
|
||||
char roofing_filter;
|
||||
struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv;
|
||||
struct newcat_roofing_filter *roofing_filters = priv_caps->roofing_filters;
|
||||
char main_sub_vfo = '0';
|
||||
char rf_vfo = 'X';
|
||||
char roofing_filter_choice = 0;
|
||||
int err;
|
||||
int n;
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||
|
||||
if (priv_caps == NULL)
|
||||
{
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
|
||||
if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
|
||||
{
|
||||
main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0';
|
||||
}
|
||||
|
||||
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%c", main_sub_vfo,
|
||||
cat_term);
|
||||
if (!newcat_valid_command(rig, "RF"))
|
||||
{
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
|
||||
for (index = 0; roofing_filters[index].index >= 0; index++)
|
||||
{
|
||||
struct newcat_roofing_filter *current_filter = &roofing_filters[index];
|
||||
char set_value = current_filter->set_value;
|
||||
if (set_value == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
roofing_filter_choice = set_value;
|
||||
|
||||
if (current_filter->index == index)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (roofing_filter_choice == 0)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%1d%c", main_sub_vfo, roofing_filter_choice, cat_term);
|
||||
|
||||
if (RIG_OK != (err = newcat_set_cmd(rig)))
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width)
|
||||
{
|
||||
struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv;
|
||||
int index = -1;
|
||||
int i;
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||
|
||||
if (priv_caps == NULL)
|
||||
{
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
|
||||
for (i = 0; i < priv_caps->roofing_filter_count; i++)
|
||||
{
|
||||
struct newcat_roofing_filter *current_filter = &priv_caps->roofing_filters[i];
|
||||
char set_value = current_filter->set_value;
|
||||
|
||||
// Skip get-only values and optional filters
|
||||
if (set_value == 0 || current_filter->optional)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
index = i;
|
||||
|
||||
// The last filter is always the narrowest
|
||||
if (current_filter->width < width)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
return set_roofing_filter(rig, vfo, index);
|
||||
}
|
||||
|
||||
static int get_roofing_filter(RIG *rig, vfo_t vfo, struct newcat_roofing_filter **roofing_filter)
|
||||
{
|
||||
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
|
||||
struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv;
|
||||
struct newcat_roofing_filter *roofing_filters = priv_caps->roofing_filters;
|
||||
char roofing_filter_choice;
|
||||
char main_sub_vfo = '0';
|
||||
char rf_vfo = 'X';
|
||||
int err;
|
||||
int n;
|
||||
int i;
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||
|
||||
if (priv_caps == NULL)
|
||||
{
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
|
||||
if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)
|
||||
{
|
||||
main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0';
|
||||
}
|
||||
|
||||
snprintf(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%c", main_sub_vfo, cat_term);
|
||||
|
||||
if (RIG_OK != (err = newcat_get_cmd(rig)))
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
n = sscanf(priv->ret_data, "RF%c%c", &rf_vfo, &roofing_filter);
|
||||
n = sscanf(priv->ret_data, "RF%c%c", &rf_vfo, &roofing_filter_choice);
|
||||
|
||||
if (n != 2)
|
||||
{
|
||||
|
@ -6254,7 +6386,21 @@ static char get_roofing_filter(RIG *rig, vfo_t vfo)
|
|||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
return roofing_filter;
|
||||
for (i = 0; i < priv_caps->roofing_filter_count; i++)
|
||||
{
|
||||
struct newcat_roofing_filter *current_filter = &roofing_filters[i];
|
||||
if (current_filter->get_value == roofing_filter_choice)
|
||||
{
|
||||
*roofing_filter = current_filter;
|
||||
return RIG_OK;
|
||||
}
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_ERR,
|
||||
"%s: Expected a valid roofing filter but got %c from '%s'\n", __func__,
|
||||
roofing_filter_choice, priv->ret_data);
|
||||
|
||||
return RIG_ENIMPL;
|
||||
}
|
||||
|
||||
int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
|
||||
|
@ -6615,25 +6761,12 @@ int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width)
|
|||
|
||||
if (w == 0) // then we need to know the roofing filter
|
||||
{
|
||||
char roofing_filter = get_roofing_filter(rig, vfo);
|
||||
struct newcat_roofing_filter *roofing_filter;
|
||||
int err = get_roofing_filter(rig, vfo, &roofing_filter);
|
||||
|
||||
switch (roofing_filter)
|
||||
if (err == RIG_OK)
|
||||
{
|
||||
case '6': *width = 12000; break;
|
||||
|
||||
case '7': *width = 3000; break;
|
||||
|
||||
case '8': *width = 1200; break;
|
||||
|
||||
case '9': *width = 600; break;
|
||||
|
||||
case 'A': *width = 300; break;
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR,
|
||||
"%s: Expected roofing filter 6,7,8,9,A but got %c from '%s'\n", __func__,
|
||||
roofing_filter, priv->ret_data);
|
||||
return RIG_OK;
|
||||
*width = roofing_filter->width;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7009,7 +7142,7 @@ int newcat_vfomem_toggle(RIG *rig)
|
|||
* "?;" busy please wait response; the command is not resent but up to
|
||||
* 'retry' retries to receive a valid response are made.
|
||||
*/
|
||||
int newcat_get_cmd_ext(RIG *rig, int question_mark_response_means_rejected)
|
||||
int newcat_get_cmd(RIG *rig)
|
||||
{
|
||||
struct rig_state *state = &rig->state;
|
||||
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
|
||||
|
@ -7169,7 +7302,7 @@ int newcat_get_cmd_ext(RIG *rig, int question_mark_response_means_rejected)
|
|||
break; /* retry */
|
||||
|
||||
case '?':
|
||||
if (question_mark_response_means_rejected)
|
||||
if (priv->question_mark_response_means_rejected)
|
||||
{
|
||||
/* Some commands, like MR and MC return "?;" when choosing a channel that doesn't exist */
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: Command rejected: '%s'\n", __func__, priv->cmd_str);
|
||||
|
@ -7210,11 +7343,6 @@ int newcat_get_cmd_ext(RIG *rig, int question_mark_response_means_rejected)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int newcat_get_cmd(RIG *rig)
|
||||
{
|
||||
return newcat_get_cmd_ext(rig, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes a null terminated command string from priv->cmd_str to the
|
||||
* CAT port that is not expected to have a response.
|
||||
|
@ -7225,7 +7353,7 @@ int newcat_get_cmd(RIG *rig)
|
|||
* "?;" busy please wait response; the command is not resent but up to
|
||||
* 'retry' retries to receive a valid response are made.
|
||||
*/
|
||||
int newcat_set_cmd_ext(RIG *rig, int question_mark_response_means_rejected)
|
||||
int newcat_set_cmd(RIG *rig)
|
||||
{
|
||||
struct rig_state *state = &rig->state;
|
||||
struct newcat_priv_data *priv = (struct newcat_priv_data *)rig->state.priv;
|
||||
|
@ -7304,7 +7432,7 @@ int newcat_set_cmd_ext(RIG *rig, int question_mark_response_means_rejected)
|
|||
break; /* retry */
|
||||
|
||||
case '?':
|
||||
if (question_mark_response_means_rejected)
|
||||
if (priv->question_mark_response_means_rejected)
|
||||
{
|
||||
/* Some commands, like MR and MC return "?;" when choosing a channel that doesn't exist */
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: Command rejected: '%s'\n", __func__, priv->cmd_str);
|
||||
|
@ -7351,11 +7479,6 @@ int newcat_set_cmd_ext(RIG *rig, int question_mark_response_means_rejected)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int newcat_set_cmd(RIG *rig)
|
||||
{
|
||||
return newcat_set_cmd_ext(rig, 0);
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
rmode_t mode;
|
||||
|
|
|
@ -72,12 +72,34 @@ typedef char ncboolean;
|
|||
extern const struct confparams newcat_cfg_params[];
|
||||
|
||||
/*
|
||||
* future - private data
|
||||
*
|
||||
* FIXME: Does this need to be exposed to the application/frontend through
|
||||
* rig_caps.priv? I'm guessing not since it's private to the backend. -N0NB
|
||||
* Private caps for newcat rigs
|
||||
*/
|
||||
|
||||
#define NEWCAT_ROOFING_FILTER_COUNT 12
|
||||
|
||||
struct newcat_roofing_filter
|
||||
{
|
||||
/* Index of the roofing filter in the ext level combo */
|
||||
int index;
|
||||
/* Value to set the selected roofing filter, must be 0 for a get-only choice */
|
||||
char set_value;
|
||||
/* Value returned by the rig for this roofing filter, must be 0 for a set-only choice */
|
||||
char get_value;
|
||||
/* Width of the filter in Hz */
|
||||
int width;
|
||||
/* 0 = Always available, 1 = Optional filter */
|
||||
int optional;
|
||||
};
|
||||
|
||||
struct newcat_priv_caps
|
||||
{
|
||||
int roofing_filter_count;
|
||||
struct newcat_roofing_filter roofing_filters[NEWCAT_ROOFING_FILTER_COUNT];
|
||||
};
|
||||
|
||||
/*
|
||||
* Private state for newcat rigs
|
||||
*/
|
||||
struct newcat_priv_data
|
||||
{
|
||||
unsigned int
|
||||
|
@ -96,9 +118,9 @@ struct newcat_priv_data
|
|||
struct timespec cache_start;
|
||||
char last_if_response[NEWCAT_DATA_LEN];
|
||||
int poweron; /* to prevent powering on more than once */
|
||||
int question_mark_response_means_rejected;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Functions considered to be Stable:
|
||||
*
|
||||
|
@ -132,9 +154,7 @@ struct newcat_priv_data
|
|||
*/
|
||||
|
||||
int newcat_get_cmd(RIG *rig);
|
||||
int newcat_get_cmd_ext(RIG *rig, int question_mark_response_means_rejected);
|
||||
int newcat_set_cmd(RIG *rig);
|
||||
int newcat_set_cmd_ext(RIG *rig, int question_mark_response_means_rejected);
|
||||
|
||||
int newcat_init(RIG *rig);
|
||||
int newcat_cleanup(RIG *rig);
|
||||
|
@ -197,5 +217,8 @@ rmode_t newcat_rmode(char mode);
|
|||
char newcat_modechar(rmode_t rmode);
|
||||
rmode_t newcat_rmode_width(RIG *rig, vfo_t vfo, char mode, pbwidth_t *width);
|
||||
|
||||
#define TOKEN_BACKEND(t) (t)
|
||||
|
||||
#define TOK_ROOFING_FILTER TOKEN_BACKEND(100)
|
||||
|
||||
#endif /* _NEWCAT_H */
|
||||
|
|
Ładowanie…
Reference in New Issue