drivers: Factor out std_*_idx*().

This commit is contained in:
Uwe Hermann 2017-07-25 23:12:09 +02:00
parent 94e64a0b89
commit 697fb6ddfc
22 changed files with 378 additions and 680 deletions

View File

@ -217,9 +217,7 @@ static int config_set(uint32_t key, GVariant *data,
{
struct dev_context *devc;
uint64_t samplerate;
const char *tmp_str;
unsigned int i;
int ret;
int ret, idx;
(void)cg;
@ -238,17 +236,11 @@ static int config_set(uint32_t key, GVariant *data,
case SR_CONF_LIMIT_MSEC:
ret = sr_sw_limits_config_set(&devc->limits, key, data);
break;
case SR_CONF_DATA_SOURCE: {
tmp_str = g_variant_get_string(data, NULL);
for (i = 0; i < ARRAY_SIZE(data_sources); i++)
if (!strcmp(tmp_str, data_sources[i])) {
devc->data_source = i;
break;
}
if (i == ARRAY_SIZE(data_sources))
return SR_ERR;
case SR_CONF_DATA_SOURCE:
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
return SR_ERR_ARG;
devc->data_source = idx;
break;
}
default:
ret = SR_ERR_NA;
}

View File

@ -134,8 +134,7 @@ static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc;
const char *tmp_str;
unsigned int i;
int idx;
(void)cg;
@ -145,17 +144,11 @@ static int config_set(uint32_t key, GVariant *data,
case SR_CONF_LIMIT_SAMPLES:
case SR_CONF_LIMIT_MSEC:
return sr_sw_limits_config_set(&devc->limits, key, data);
case SR_CONF_DATA_SOURCE: {
tmp_str = g_variant_get_string(data, NULL);
for (i = 0; i < ARRAY_SIZE(data_sources); i++)
if (!strcmp(tmp_str, data_sources[i])) {
devc->data_source = i;
break;
}
if (i == ARRAY_SIZE(data_sources))
return SR_ERR;
case SR_CONF_DATA_SOURCE:
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
return SR_ERR_ARG;
devc->data_source = idx;
break;
}
default:
return SR_ERR_NA;
}

View File

@ -234,21 +234,6 @@ static int config_get(uint32_t key, GVariant **data,
return SR_OK;
}
static int find_str(const char *str, const char **strings, int array_size)
{
int idx, i;
idx = -1;
for (i = 0; i < array_size; i++) {
if (!strcmp(str, strings[i])) {
idx = i;
break;
}
}
return idx;
}
static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
@ -256,7 +241,6 @@ static int config_set(uint32_t key, GVariant *data,
struct sr_channel *ch;
gdouble dval;
int channel, ret, ival;
const char *sval;
gboolean bval;
ret = SR_OK;
@ -264,11 +248,8 @@ static int config_set(uint32_t key, GVariant *data,
if (!cg) {
switch (key) {
case SR_CONF_CHANNEL_CONFIG:
sval = g_variant_get_string(data, NULL);
if ((ival = find_str(sval, ARRAY_AND_SIZE(channel_modes))) == -1) {
ret = SR_ERR_ARG;
break;
}
if ((ival = std_str_idx(data, ARRAY_AND_SIZE(channel_modes))) < 0)
return SR_ERR_ARG;
if (devc->model->channel_modes && (1 << ival) == 0) {
/* Not supported on this model. */
ret = SR_ERR_ARG;

View File

@ -197,10 +197,8 @@ static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc;
uint64_t tmp_u64, low, high;
unsigned int i;
int tmp, ret;
const char *tmp_str;
uint64_t tmp_u64;
int tmp, ret, idx;
(void)cg;
@ -217,27 +215,15 @@ static int config_set(uint32_t key, GVariant *data,
ret = cem_dt_885x_recording_set(sdi, g_variant_get_boolean(data));
break;
case SR_CONF_SPL_WEIGHT_FREQ:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "A"))
ret = cem_dt_885x_weight_freq_set(sdi,
SR_MQFLAG_SPL_FREQ_WEIGHT_A);
else if (!strcmp(tmp_str, "C"))
ret = cem_dt_885x_weight_freq_set(sdi,
SR_MQFLAG_SPL_FREQ_WEIGHT_C);
else
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_freq))) < 0)
return SR_ERR_ARG;
break;
return cem_dt_885x_weight_freq_set(sdi, (weight_freq[idx][0] == 'A') ?
SR_MQFLAG_SPL_FREQ_WEIGHT_A : SR_MQFLAG_SPL_FREQ_WEIGHT_C);
case SR_CONF_SPL_WEIGHT_TIME:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "F"))
ret = cem_dt_885x_weight_time_set(sdi,
SR_MQFLAG_SPL_TIME_WEIGHT_F);
else if (!strcmp(tmp_str, "S"))
ret = cem_dt_885x_weight_time_set(sdi,
SR_MQFLAG_SPL_TIME_WEIGHT_S);
else
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_time))) < 0)
return SR_ERR_ARG;
break;
return cem_dt_885x_weight_time_set(sdi, (weight_time[idx][0] == 'F') ?
SR_MQFLAG_SPL_TIME_WEIGHT_F : SR_MQFLAG_SPL_TIME_WEIGHT_S);
case SR_CONF_HOLD_MAX:
tmp = g_variant_get_boolean(data) ? SR_MQFLAG_MAX : 0;
ret = cem_dt_885x_holdmode_set(sdi, tmp);
@ -247,28 +233,18 @@ static int config_set(uint32_t key, GVariant *data,
ret = cem_dt_885x_holdmode_set(sdi, tmp);
break;
case SR_CONF_SPL_MEASUREMENT_RANGE:
g_variant_get(data, "(tt)", &low, &high);
ret = SR_ERR_ARG;
for (i = 0; i < ARRAY_SIZE(meas_ranges); i++) {
if (meas_ranges[i][0] == low && meas_ranges[i][1] == high) {
ret = cem_dt_885x_meas_range_set(sdi, low, high);
break;
}
}
break;
if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(meas_ranges))) < 0)
return SR_ERR_ARG;
return cem_dt_885x_meas_range_set(sdi, meas_ranges[idx][0], meas_ranges[idx][1]);
case SR_CONF_POWER_OFF:
if (g_variant_get_boolean(data))
ret = cem_dt_885x_power_off(sdi);
break;
case SR_CONF_DATA_SOURCE:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "Live"))
devc->cur_data_source = DATA_SOURCE_LIVE;
else if (!strcmp(tmp_str, "Memory"))
devc->cur_data_source = DATA_SOURCE_MEMORY;
else
return SR_ERR;
devc->enable_data_source_memory = devc->cur_data_source == DATA_SOURCE_MEMORY;
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
return SR_ERR_ARG;
devc->cur_data_source = idx;
devc->enable_data_source_memory = (idx == DATA_SOURCE_MEMORY);
break;
default:
ret = SR_ERR_NA;

View File

@ -265,8 +265,6 @@ static int config_set(uint32_t key, GVariant *data,
struct sr_channel *ch;
GSList *l;
int logic_pattern, analog_pattern;
unsigned int i;
const char *stropt;
devc = sdi->priv;
@ -293,21 +291,9 @@ static int config_set(uint32_t key, GVariant *data,
case SR_CONF_PATTERN_MODE:
if (!cg)
return SR_ERR_CHANNEL_GROUP;
stropt = g_variant_get_string(data, NULL);
logic_pattern = analog_pattern = -1;
for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
if (!strcmp(stropt, logic_pattern_str[i])) {
logic_pattern = i;
break;
}
}
for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
if (!strcmp(stropt, analog_pattern_str[i])) {
analog_pattern = i;
break;
}
}
if (logic_pattern == -1 && analog_pattern == -1)
logic_pattern = std_str_idx(data, ARRAY_AND_SIZE(logic_pattern_str));
analog_pattern = std_str_idx(data, ARRAY_AND_SIZE(analog_pattern_str));
if (logic_pattern < 0 && analog_pattern < 0)
return SR_ERR_ARG;
for (l = cg->channels; l; l = l->next) {
ch = l->data;

View File

@ -67,7 +67,7 @@ static const uint32_t devopts[] = {
SR_CONF_CLOCK_EDGE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
};
static const char *const signal_edge_names[] = {
static const char *signal_edge_names[] = {
[DS_EDGE_RISING] = "rising",
[DS_EDGE_FALLING] = "falling",
};
@ -380,7 +380,7 @@ static int config_get(uint32_t key, GVariant **data,
{
struct dev_context *devc;
struct sr_usb_dev_inst *usb;
unsigned int i, voltage_range;
int idx;
(void)cg;
@ -402,15 +402,11 @@ static int config_get(uint32_t key, GVariant **data,
break;
case SR_CONF_VOLTAGE_THRESHOLD:
if (!strcmp(devc->profile->model, "DSLogic")) {
voltage_range = 0;
for (i = 0; i < ARRAY_SIZE(voltage_thresholds); i++)
if (voltage_thresholds[i][0] == devc->cur_threshold) {
voltage_range = i;
break;
}
*data = std_gvar_tuple_double(voltage_thresholds[voltage_range][0],
voltage_thresholds[voltage_range][1]);
if ((idx = std_double_tuple_idx_d0(devc->cur_threshold,
ARRAY_AND_SIZE(voltage_thresholds))) < 0)
return SR_ERR_BUG;
*data = std_gvar_tuple_double(voltage_thresholds[idx][0],
voltage_thresholds[idx][1]);
} else {
*data = std_gvar_tuple_double(devc->cur_threshold, devc->cur_threshold);
}
@ -431,8 +427,8 @@ static int config_get(uint32_t key, GVariant **data,
*data = g_variant_new_boolean(devc->continuous_mode);
break;
case SR_CONF_CLOCK_EDGE:
i = devc->clock_edge;
if (i >= ARRAY_SIZE(signal_edge_names))
idx = devc->clock_edge;
if (idx >= (int)ARRAY_SIZE(signal_edge_names))
return SR_ERR_BUG;
*data = g_variant_new_string(signal_edge_names[0]);
break;
@ -443,34 +439,11 @@ static int config_get(uint32_t key, GVariant **data,
return SR_OK;
}
/*
* Helper for mapping a string-typed configuration value to an index
* within a table of possible values.
*/
static int lookup_index(GVariant *value, const char *const *table, int len)
{
const char *entry;
int i;
entry = g_variant_get_string(value, NULL);
if (!entry)
return -1;
/* Linear search is fine for very small tables. */
for (i = 0; i < len; i++) {
if (strcmp(entry, table[i]) == 0)
return i;
}
return -1;
}
static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc;
uint64_t arg;
int i, ret;
int idx, ret;
gdouble low, high;
(void)cg;
@ -484,15 +457,9 @@ static int config_set(uint32_t key, GVariant *data,
switch (key) {
case SR_CONF_SAMPLERATE:
arg = g_variant_get_uint64(data);
for (i = 0; i < devc->num_samplerates; i++) {
if (devc->samplerates[i] == arg) {
devc->cur_samplerate = arg;
break;
}
}
if (i == devc->num_samplerates)
ret = SR_ERR_ARG;
if ((idx = std_u64_idx(data, devc->samplerates, devc->num_samplerates)) < 0)
return SR_ERR_ARG;
devc->cur_samplerate = devc->samplerates[idx];
break;
case SR_CONF_LIMIT_SAMPLES:
devc->limit_samples = g_variant_get_uint64(data);
@ -502,18 +469,13 @@ static int config_set(uint32_t key, GVariant *data,
ret = (devc->capture_ratio > 100) ? SR_ERR : SR_OK;
break;
case SR_CONF_VOLTAGE_THRESHOLD:
g_variant_get(data, "(dd)", &low, &high);
if (!strcmp(devc->profile->model, "DSLogic")) {
for (i = 0; (unsigned int)i < ARRAY_SIZE(voltage_thresholds); i++) {
if (fabs(voltage_thresholds[i][0] - low) < 0.1 &&
fabs(voltage_thresholds[i][1] - high) < 0.1) {
devc->cur_threshold =
voltage_thresholds[i][0];
break;
}
}
if ((idx = std_double_tuple_idx(data, ARRAY_AND_SIZE(voltage_thresholds))) < 0)
return SR_ERR_ARG;
devc->cur_threshold = voltage_thresholds[idx][0];
ret = dslogic_fpga_firmware_upload(sdi);
} else {
g_variant_get(data, "(dd)", &low, &high);
ret = dslogic_set_voltage_threshold(sdi, (low + high) / 2.0);
}
break;
@ -524,10 +486,9 @@ static int config_set(uint32_t key, GVariant *data,
devc->continuous_mode = g_variant_get_boolean(data);
break;
case SR_CONF_CLOCK_EDGE:
i = lookup_index(data, ARRAY_AND_SIZE(signal_edge_names));
if (i < 0)
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(signal_edge_names))) < 0)
return SR_ERR_ARG;
devc->clock_edge = i;
devc->clock_edge = idx;
break;
default:
ret = SR_ERR_NA;

View File

@ -488,8 +488,7 @@ static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc;
uint64_t arg;
int i, ret;
int idx, ret;
(void)cg;
@ -502,15 +501,9 @@ static int config_set(uint32_t key, GVariant *data,
switch (key) {
case SR_CONF_SAMPLERATE:
arg = g_variant_get_uint64(data);
for (i = 0; i < devc->num_samplerates; i++) {
if (devc->samplerates[i] == arg) {
devc->cur_samplerate = arg;
break;
}
}
if (i == devc->num_samplerates)
ret = SR_ERR_ARG;
if ((idx = std_u64_idx(data, devc->samplerates, devc->num_samplerates)) < 0)
return SR_ERR_ARG;
devc->cur_samplerate = devc->samplerates[idx];
break;
case SR_CONF_LIMIT_SAMPLES:
devc->limit_samples = g_variant_get_uint64(data);

View File

@ -47,17 +47,6 @@ enum {
CG_DIGITAL,
};
static int check_manufacturer(const char *manufacturer)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(manufacturers); i++)
if (!strcmp(manufacturer, manufacturers[i]))
return SR_OK;
return SR_ERR;
}
static struct sr_dev_inst *hmo_probe_serial_device(struct sr_scpi_dev_inst *scpi)
{
struct sr_dev_inst *sdi;
@ -73,7 +62,7 @@ static struct sr_dev_inst *hmo_probe_serial_device(struct sr_scpi_dev_inst *scpi
goto fail;
}
if (check_manufacturer(hw_info->manufacturer) != SR_OK)
if (std_str_idx_s(hw_info->manufacturer, ARRAY_AND_SIZE(manufacturers)) < 0)
goto fail;
sdi = g_malloc0(sizeof(struct sr_dev_inst));
@ -269,14 +258,13 @@ static int config_get(uint32_t key, GVariant **data,
static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
int ret, cg_type;
int ret, cg_type, idx;
unsigned int i, j;
char command[MAX_COMMAND_SIZE], float_str[30];
struct dev_context *devc;
const struct scope_config *model;
struct scope_state *state;
const char *tmp;
uint64_t p, q;
double tmp_d;
gboolean update_sample_rate;
@ -316,50 +304,35 @@ static int config_set(uint32_t key, GVariant *data,
case SR_CONF_VDIV:
if (cg_type == CG_NONE)
return SR_ERR_CHANNEL_GROUP;
g_variant_get(data, "(tt)", &p, &q);
for (i = 0; i < model->num_vdivs; i++) {
if (p != (*model->vdivs)[i][0] ||
q != (*model->vdivs)[i][1])
if ((idx = std_u64_tuple_idx(data, *model->vdivs, model->num_vdivs)) < 0)
return SR_ERR_ARG;
for (j = 1; j <= model->analog_channels; j++) {
if (cg != devc->analog_groups[j - 1])
continue;
for (j = 1; j <= model->analog_channels; j++) {
if (cg != devc->analog_groups[j - 1])
continue;
state->analog_channels[j - 1].vdiv = i;
g_ascii_formatd(float_str, sizeof(float_str), "%E", (float) p / q);
g_snprintf(command, sizeof(command),
(*model->scpi_dialect)[SCPI_CMD_SET_VERTICAL_DIV],
j, float_str);
if (sr_scpi_send(sdi->conn, command) != SR_OK ||
sr_scpi_get_opc(sdi->conn) != SR_OK)
return SR_ERR;
break;
}
ret = SR_OK;
state->analog_channels[j - 1].vdiv = idx;
g_ascii_formatd(float_str, sizeof(float_str), "%E",
(float) (*model->vdivs)[idx][0] / (*model->vdivs)[idx][1]);
g_snprintf(command, sizeof(command),
(*model->scpi_dialect)[SCPI_CMD_SET_VERTICAL_DIV],
j, float_str);
if (sr_scpi_send(sdi->conn, command) != SR_OK ||
sr_scpi_get_opc(sdi->conn) != SR_OK)
return SR_ERR;
break;
}
ret = SR_OK;
break;
case SR_CONF_TIMEBASE:
g_variant_get(data, "(tt)", &p, &q);
for (i = 0; i < model->num_timebases; i++) {
if (p != (*model->timebases)[i][0] ||
q != (*model->timebases)[i][1])
continue;
state->timebase = i;
g_ascii_formatd(float_str, sizeof(float_str), "%E", (float) p / q);
g_snprintf(command, sizeof(command),
(*model->scpi_dialect)[SCPI_CMD_SET_TIMEBASE],
float_str);
ret = sr_scpi_send(sdi->conn, command);
update_sample_rate = TRUE;
break;
}
if ((idx = std_u64_tuple_idx(data, *model->timebases, model->num_timebases)) < 0)
return SR_ERR_ARG;
state->timebase = idx;
g_ascii_formatd(float_str, sizeof(float_str), "%E",
(float) (*model->timebases)[idx][0] / (*model->timebases)[idx][1]);
g_snprintf(command, sizeof(command),
(*model->scpi_dialect)[SCPI_CMD_SET_TIMEBASE],
float_str);
ret = sr_scpi_send(sdi->conn, command);
update_sample_rate = TRUE;
break;
case SR_CONF_HORIZ_TRIGGERPOS:
tmp_d = g_variant_get_double(data);

View File

@ -390,10 +390,7 @@ static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc;
uint64_t p, q;
int tmp_int, ch_idx;
unsigned int i;
const char *tmp_str;
int ch_idx, idx;
devc = sdi->priv;
if (!cg) {
@ -420,30 +417,16 @@ static int config_set(uint32_t key, GVariant *data,
return SR_ERR_ARG;
switch (key) {
case SR_CONF_VDIV:
g_variant_get(data, "(tt)", &p, &q);
tmp_int = -1;
for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
if (vdivs[i][0] == p && vdivs[i][1] == q) {
tmp_int = i;
break;
}
}
if (tmp_int >= 0) {
devc->voltage[ch_idx] = tmp_int;
hantek_6xxx_update_vdiv(sdi);
} else
if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(vdivs))) < 0)
return SR_ERR_ARG;
devc->voltage[ch_idx] = idx;
hantek_6xxx_update_vdiv(sdi);
break;
case SR_CONF_COUPLING:
tmp_str = g_variant_get_string(data, NULL);
for (i = 0; i < devc->coupling_tab_size; i++) {
if (!strcmp(tmp_str, devc->coupling_vals[i])) {
devc->coupling[ch_idx] = i;
break;
}
}
if (i == devc->coupling_tab_size)
if ((idx = std_str_idx(data, devc->coupling_vals,
devc->coupling_tab_size)) < 0)
return SR_ERR_ARG;
devc->coupling[ch_idx] = idx;
break;
default:
return SR_ERR_NA;

View File

@ -475,10 +475,7 @@ static int config_set(uint32_t key, GVariant *data,
{
struct dev_context *devc;
double tmp_double;
uint64_t tmp_u64, p, q;
int tmp_int, ch_idx;
unsigned int i;
const char *tmp_str;
int ch_idx, idx;
devc = sdi->priv;
if (!cg) {
@ -487,10 +484,9 @@ static int config_set(uint32_t key, GVariant *data,
devc->limit_frames = g_variant_get_uint64(data);
break;
case SR_CONF_TRIGGER_SLOPE:
tmp_str = g_variant_get_string(data, NULL);
if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r'))
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_slopes))) < 0)
return SR_ERR_ARG;
devc->triggerslope = (tmp_str[0] == 'r')
devc->triggerslope = (trigger_slopes[idx][0] == 'r')
? SLOPE_POSITIVE : SLOPE_NEGATIVE;
break;
case SR_CONF_HORIZ_TRIGGERPOS:
@ -502,40 +498,19 @@ static int config_set(uint32_t key, GVariant *data,
devc->triggerposition = tmp_double;
break;
case SR_CONF_BUFFERSIZE:
tmp_u64 = g_variant_get_uint64(data);
for (i = 0; i < NUM_BUFFER_SIZES; i++) {
if (devc->profile->buffersizes[i] == tmp_u64) {
devc->framesize = tmp_u64;
break;
}
}
if (i == NUM_BUFFER_SIZES)
if ((idx = std_u64_idx(data, devc->profile->buffersizes, NUM_BUFFER_SIZES)) < 0)
return SR_ERR_ARG;
devc->framesize = devc->profile->buffersizes[idx];
break;
case SR_CONF_TIMEBASE:
g_variant_get(data, "(tt)", &p, &q);
tmp_int = -1;
for (i = 0; i < ARRAY_SIZE(timebases); i++) {
if (timebases[i][0] == p && timebases[i][1] == q) {
tmp_int = i;
break;
}
}
if (tmp_int >= 0)
devc->timebase = tmp_int;
else
if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(timebases))) < 0)
return SR_ERR_ARG;
devc->timebase = idx;
break;
case SR_CONF_TRIGGER_SOURCE:
tmp_str = g_variant_get_string(data, NULL);
for (i = 0; trigger_sources[i]; i++) {
if (!strcmp(tmp_str, trigger_sources[i])) {
devc->triggersource = g_strdup(tmp_str);
break;
}
}
if (trigger_sources[i] == 0)
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_sources))) < 0)
return SR_ERR_ARG;
devc->triggersource = g_strdup(trigger_sources[idx]);
break;
default:
return SR_ERR_NA;
@ -552,29 +527,14 @@ static int config_set(uint32_t key, GVariant *data,
devc->filter[ch_idx] = g_variant_get_boolean(data);
break;
case SR_CONF_VDIV:
g_variant_get(data, "(tt)", &p, &q);
tmp_int = -1;
for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
if (vdivs[i][0] == p && vdivs[i][1] == q) {
tmp_int = i;
break;
}
}
if (tmp_int >= 0) {
devc->voltage[ch_idx] = tmp_int;
} else
if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(vdivs))) < 0)
return SR_ERR_ARG;
devc->voltage[ch_idx] = idx;
break;
case SR_CONF_COUPLING:
tmp_str = g_variant_get_string(data, NULL);
for (i = 0; coupling[i]; i++) {
if (!strcmp(tmp_str, coupling[i])) {
devc->coupling[ch_idx] = i;
break;
}
}
if (coupling[i] == 0)
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(coupling))) < 0)
return SR_ERR_ARG;
devc->coupling[ch_idx] = idx;
break;
default:
return SR_ERR_NA;

View File

@ -283,65 +283,12 @@ static int dev_close(struct sr_dev_inst *sdi)
return SR_OK;
}
static int find_in_array(GVariant *data, const GVariantType *type,
const void *arr, int n)
{
const char * const *sarr;
const char *s;
const uint64_t *u64arr;
const uint8_t *u8arr;
uint64_t u64;
uint8_t u8;
int i;
if (!g_variant_is_of_type(data, type))
return -1;
switch (g_variant_classify(data)) {
case G_VARIANT_CLASS_STRING:
s = g_variant_get_string(data, NULL);
sarr = arr;
for (i = 0; i < n; i++)
if (!strcmp(s, sarr[i]))
return i;
break;
case G_VARIANT_CLASS_UINT64:
u64 = g_variant_get_uint64(data);
u64arr = arr;
for (i = 0; i < n; i++)
if (u64 == u64arr[i])
return i;
break;
case G_VARIANT_CLASS_BYTE:
u8 = g_variant_get_byte(data);
u8arr = arr;
for (i = 0; i < n; i++)
if (u8 == u8arr[i])
return i;
default:
break;
}
return -1;
}
static int reverse_map(uint8_t u, const uint8_t *arr, int n)
{
GVariant *v = g_variant_new_byte(u);
int i = find_in_array(v, G_VARIANT_TYPE_BYTE, arr, n);
g_variant_unref(v);
return i;
}
static int config_get(uint32_t key, GVariant **data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc = sdi->priv;
struct parport *port;
int i, ch = -1;
int idx, ch = -1;
if (cg) /* sr_config_get will validate cg using config_list */
ch = ((struct sr_channel *)cg->channels->data)->index;
@ -358,11 +305,9 @@ static int config_get(uint32_t key, GVariant **data,
*data = g_variant_new_uint64(samplerates[devc->rate]);
break;
case SR_CONF_TRIGGER_SOURCE:
i = reverse_map(devc->cctl[0] & 0xC0, ARRAY_AND_SIZE(trigger_sources_map));
if (i == -1)
return SR_ERR;
else
*data = g_variant_new_string(trigger_sources[i]);
if ((idx = std_u8_idx_s(devc->cctl[0] & 0xC0, ARRAY_AND_SIZE(trigger_sources_map))) < 0)
return SR_ERR_BUG;
*data = g_variant_new_string(trigger_sources[idx]);
break;
case SR_CONF_TRIGGER_SLOPE:
if (devc->edge >= ARRAY_SIZE(trigger_slopes))
@ -377,23 +322,18 @@ static int config_get(uint32_t key, GVariant **data,
if (ch == -1) {
return SR_ERR_CHANNEL_GROUP;
} else {
i = reverse_map(devc->cctl[ch] & 0x33, ARRAY_AND_SIZE(vdivs_map));
if (i == -1)
return SR_ERR;
else
*data = g_variant_new("(tt)", vdivs[i][0],
vdivs[i][1]);
if ((idx = std_u8_idx_s(devc->cctl[ch] & 0x33, ARRAY_AND_SIZE(vdivs_map))) < 0)
return SR_ERR_BUG;
*data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
}
break;
case SR_CONF_COUPLING:
if (ch == -1) {
return SR_ERR_CHANNEL_GROUP;
} else {
i = reverse_map(devc->cctl[ch] & 0x0C, ARRAY_AND_SIZE(coupling_map));
if (i == -1)
return SR_ERR;
else
*data = g_variant_new_string(coupling[i]);
if ((idx = std_u8_idx_s(devc->cctl[ch] & 0x0C, ARRAY_AND_SIZE(coupling_map))) < 0)
return SR_ERR_BUG;
*data = g_variant_new_string(coupling[idx]);
}
break;
case SR_CONF_PROBE_FACTOR:
@ -413,8 +353,8 @@ static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc = sdi->priv;
int i, ch = -1;
uint64_t u, v;
int idx, ch = -1;
uint64_t u;
if (cg) /* sr_config_set will validate cg using config_list */
ch = ((struct sr_channel *)cg->channels->data)->index;
@ -424,37 +364,24 @@ static int config_set(uint32_t key, GVariant *data,
devc->frame_limit = g_variant_get_uint64(data);
break;
case SR_CONF_SAMPLERATE:
i = find_in_array(data, G_VARIANT_TYPE_UINT64,
ARRAY_AND_SIZE(samplerates));
if (i == -1)
if ((idx = std_u64_idx(data, ARRAY_AND_SIZE(samplerates))) < 0)
return SR_ERR_ARG;
else
devc->rate = i;
devc->rate = idx;
break;
case SR_CONF_TRIGGER_SOURCE:
i = find_in_array(data, G_VARIANT_TYPE_STRING,
ARRAY_AND_SIZE(trigger_sources));
if (i == -1)
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_sources))) < 0)
return SR_ERR_ARG;
else
devc->cctl[0] = (devc->cctl[0] & 0x3F)
| trigger_sources_map[i];
devc->cctl[0] = (devc->cctl[0] & 0x3F) | trigger_sources_map[idx];
break;
case SR_CONF_TRIGGER_SLOPE:
i = find_in_array(data, G_VARIANT_TYPE_STRING,
ARRAY_AND_SIZE(trigger_slopes));
if (i == -1)
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_slopes))) < 0)
return SR_ERR_ARG;
else
devc->edge = i;
devc->edge = idx;
break;
case SR_CONF_BUFFERSIZE:
i = find_in_array(data, G_VARIANT_TYPE_UINT64,
ARRAY_AND_SIZE(buffersizes));
if (i == -1)
if ((idx = std_u64_idx(data, ARRAY_AND_SIZE(buffersizes))) < 0)
return SR_ERR_ARG;
else
devc->last_step = i;
devc->last_step = idx;
break;
case SR_CONF_VDIV:
if (ch == -1) {
@ -462,28 +389,18 @@ static int config_set(uint32_t key, GVariant *data,
} else if (!g_variant_is_of_type(data, G_VARIANT_TYPE("(tt)"))) {
return SR_ERR_ARG;
} else {
g_variant_get(data, "(tt)", &u, &v);
for (i = 0; i < (int)ARRAY_SIZE(vdivs); i++)
if (vdivs[i][0] == u && vdivs[i][1] == v)
break;
if (i == ARRAY_SIZE(vdivs))
if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(vdivs))) < 0)
return SR_ERR_ARG;
else
devc->cctl[ch] = (devc->cctl[ch] & 0xCC)
| vdivs_map[i];
devc->cctl[ch] = (devc->cctl[ch] & 0xCC) | vdivs_map[idx];
}
break;
case SR_CONF_COUPLING:
if (ch == -1) {
return SR_ERR_CHANNEL_GROUP;
} else {
i = find_in_array(data, G_VARIANT_TYPE_STRING,
ARRAY_AND_SIZE(coupling));
if (i == -1)
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(coupling))) < 0)
return SR_ERR_ARG;
else
devc->cctl[ch] = (devc->cctl[ch] & 0xF3)
| coupling_map[i];
devc->cctl[ch] = (devc->cctl[ch] & 0xF3) | coupling_map[idx];
}
break;
case SR_CONF_PROBE_FACTOR:

View File

@ -247,10 +247,7 @@ static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc;
uint64_t p, q;
unsigned int i;
int tmp;
const char *tmp_str;
int idx;
(void)cg;
@ -262,49 +259,29 @@ static int config_set(uint32_t key, GVariant *data,
devc->limit_samples);
break;
case SR_CONF_SAMPLE_INTERVAL:
g_variant_get(data, "(tt)", &p, &q);
for (i = 0; i < ARRAY_SIZE(kecheng_kc_330b_sample_intervals); i++) {
if (kecheng_kc_330b_sample_intervals[i][0] != p || kecheng_kc_330b_sample_intervals[i][1] != q)
continue;
devc->sample_interval = i;
devc->config_dirty = TRUE;
break;
}
if (i == ARRAY_SIZE(kecheng_kc_330b_sample_intervals))
if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(kecheng_kc_330b_sample_intervals))) < 0)
return SR_ERR_ARG;
devc->sample_interval = idx;
devc->config_dirty = TRUE;
break;
case SR_CONF_SPL_WEIGHT_FREQ:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "A"))
tmp = SR_MQFLAG_SPL_FREQ_WEIGHT_A;
else if (!strcmp(tmp_str, "C"))
tmp = SR_MQFLAG_SPL_FREQ_WEIGHT_C;
else
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_freq))) < 0)
return SR_ERR_ARG;
devc->mqflags &= ~(SR_MQFLAG_SPL_FREQ_WEIGHT_A | SR_MQFLAG_SPL_FREQ_WEIGHT_C);
devc->mqflags |= tmp;
devc->mqflags |= (weight_freq[idx][0] == 'A') ? SR_MQFLAG_SPL_FREQ_WEIGHT_A : SR_MQFLAG_SPL_FREQ_WEIGHT_C;
devc->config_dirty = TRUE;
break;
case SR_CONF_SPL_WEIGHT_TIME:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "F"))
tmp = SR_MQFLAG_SPL_TIME_WEIGHT_F;
else if (!strcmp(tmp_str, "S"))
tmp = SR_MQFLAG_SPL_TIME_WEIGHT_S;
else
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_time))) < 0)
return SR_ERR_ARG;
devc->mqflags &= ~(SR_MQFLAG_SPL_TIME_WEIGHT_F | SR_MQFLAG_SPL_TIME_WEIGHT_S);
devc->mqflags |= tmp;
devc->mqflags |= (weight_time[idx][0] == 'F') ? SR_MQFLAG_SPL_TIME_WEIGHT_F : SR_MQFLAG_SPL_TIME_WEIGHT_S;
devc->config_dirty = TRUE;
break;
case SR_CONF_DATA_SOURCE:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "Live"))
devc->data_source = DATA_SOURCE_LIVE;
else if (!strcmp(tmp_str, "Memory"))
devc->data_source = DATA_SOURCE_MEMORY;
else
return SR_ERR;
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
return SR_ERR_ARG;
devc->data_source = idx;
devc->config_dirty = TRUE;
break;
default:

View File

@ -52,17 +52,6 @@ static const uint32_t devopts_cg_analog[] = {
SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
};
static int check_manufacturer(const char *manufacturer)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(manufacturers); i++)
if (!strcmp(manufacturer, manufacturers[i]))
return SR_OK;
return SR_ERR;
}
static struct sr_dev_inst *probe_serial_device(struct sr_scpi_dev_inst *scpi)
{
struct sr_dev_inst *sdi;
@ -78,7 +67,7 @@ static struct sr_dev_inst *probe_serial_device(struct sr_scpi_dev_inst *scpi)
goto fail;
}
if (check_manufacturer(hw_info->manufacturer) != SR_OK)
if (std_str_idx_s(hw_info->manufacturer, ARRAY_AND_SIZE(manufacturers)) < 0)
goto fail;
sdi = g_malloc0(sizeof(struct sr_dev_inst));

View File

@ -548,10 +548,8 @@ static int config_set(uint32_t key, GVariant *data,
struct sr_channel *ch;
gdouble dval;
int ch_idx;
const char *sval;
gboolean bval;
int idx;
gboolean found;
devc = sdi->priv;
@ -566,22 +564,15 @@ static int config_set(uint32_t key, GVariant *data,
case SR_CONF_LIMIT_SAMPLES:
return sr_sw_limits_config_set(&devc->limits, key, data);
case SR_CONF_CHANNEL_CONFIG:
sval = g_variant_get_string(data, NULL);
found = FALSE;
for (idx = 0; idx < (int)ARRAY_SIZE(channel_modes); idx++) {
if (!strcmp(sval, channel_modes[idx])) {
found = TRUE;
if (devc->tracking_mode == idx)
break; /* Nothing to do! */
devc->tracking_mode = idx;
if (devc->model->modelid >= LPS_304) /* No use to set anything in the smaller models. */
return lps_cmd_ok(sdi->conn, "TRACK%1d", devc->tracking_mode);
}
if (devc->model->modelid <= LPS_303) /* Only first setting possible for smaller models. */
break;
}
if (!found)
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(channel_modes))) < 0)
return SR_ERR_ARG;
if (devc->model->modelid <= LPS_303 && idx != 0)
break; /* Only first setting possible for smaller models. */
if (devc->tracking_mode == idx)
break; /* Nothing to do! */
devc->tracking_mode = idx;
if (devc->model->modelid >= LPS_304) /* No use to set anything in the smaller models. */
return lps_cmd_ok(sdi->conn, "TRACK%1d", devc->tracking_mode);
break;
default:
return SR_ERR_NA;

View File

@ -161,10 +161,8 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd
const struct sr_channel_group *cg)
{
struct dev_context *devc;
uint64_t tmp_u64, low, high;
unsigned int i;
int ret;
const char *tmp_str;
uint64_t tmp_u64;
int ret, idx;
(void)cg;
@ -178,49 +176,30 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd
ret = SR_OK;
break;
case SR_CONF_SPL_WEIGHT_FREQ:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "A"))
ret = pce_322a_weight_freq_set(sdi,
SR_MQFLAG_SPL_FREQ_WEIGHT_A);
else if (!strcmp(tmp_str, "C"))
ret = pce_322a_weight_freq_set(sdi,
SR_MQFLAG_SPL_FREQ_WEIGHT_C);
else
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_freq))) < 0)
return SR_ERR_ARG;
ret = pce_322a_weight_freq_set(sdi, (weight_freq[idx][0] == 'A') ?
SR_MQFLAG_SPL_FREQ_WEIGHT_A : SR_MQFLAG_SPL_FREQ_WEIGHT_C);
break;
case SR_CONF_SPL_WEIGHT_TIME:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "F"))
ret = pce_322a_weight_time_set(sdi,
SR_MQFLAG_SPL_TIME_WEIGHT_F);
else if (!strcmp(tmp_str, "S"))
ret = pce_322a_weight_time_set(sdi,
SR_MQFLAG_SPL_TIME_WEIGHT_S);
else
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_time))) < 0)
return SR_ERR_ARG;
ret = pce_322a_weight_time_set(sdi, (weight_time[idx][0] == 'F') ?
SR_MQFLAG_SPL_TIME_WEIGHT_F : SR_MQFLAG_SPL_TIME_WEIGHT_S);
break;
case SR_CONF_SPL_MEASUREMENT_RANGE:
g_variant_get(data, "(tt)", &low, &high);
ret = SR_ERR_ARG;
for (i = 0; i < ARRAY_SIZE(meas_ranges); i++) {
if (meas_ranges[i][0] == low && meas_ranges[i][1] == high) {
ret = pce_322a_meas_range_set(sdi, low, high);
break;
}
}
if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(meas_ranges))) < 0)
return SR_ERR_ARG;
ret = pce_322a_meas_range_set(sdi, meas_ranges[idx][0], meas_ranges[idx][1]);
break;
case SR_CONF_POWER_OFF:
if (g_variant_get_boolean(data))
ret = pce_322a_power_off(sdi);
break;
case SR_CONF_DATA_SOURCE:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "Live"))
devc->cur_data_source = DATA_SOURCE_LIVE;
else if (!strcmp(tmp_str, "Memory"))
devc->cur_data_source = DATA_SOURCE_MEMORY;
else
return SR_ERR;
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
return SR_ERR_ARG;
devc->cur_data_source = idx;
break;
default:
ret = SR_ERR_NA;

View File

@ -617,10 +617,10 @@ static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc;
uint64_t p, q;
uint64_t p;
double t_dbl;
unsigned int i, j;
int ret;
unsigned int i;
int ret, idx;
const char *tmp_str;
char buffer[16];
@ -638,16 +638,10 @@ static int config_set(uint32_t key, GVariant *data,
devc->limit_frames = g_variant_get_uint64(data);
break;
case SR_CONF_TRIGGER_SLOPE:
tmp_str = g_variant_get_string(data, NULL);
if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r')) {
sr_err("Unknown trigger slope: '%s'.",
(tmp_str) ? tmp_str : "NULL");
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_slopes))) < 0)
return SR_ERR_ARG;
}
g_free(devc->trigger_slope);
devc->trigger_slope = g_strdup((tmp_str[0] == 'r') ? "POS" : "NEG");
devc->trigger_slope = g_strdup((trigger_slopes[idx][0] == 'r') ? "POS" : "NEG");
ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
break;
case SR_CONF_HORIZ_TRIGGERPOS:
@ -671,86 +665,60 @@ static int config_set(uint32_t key, GVariant *data,
devc->trigger_level = t_dbl;
break;
case SR_CONF_TIMEBASE:
g_variant_get(data, "(tt)", &p, &q);
for (i = 0; i < devc->num_timebases; i++) {
if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
devc->timebase = (float)p / q;
g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
devc->timebase);
ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
break;
}
}
if (i == devc->num_timebases) {
sr_err("Invalid timebase index: %d.", i);
ret = SR_ERR_ARG;
}
if ((idx = std_u64_tuple_idx(data, devc->timebases, devc->num_timebases)) < 0)
return SR_ERR_ARG;
devc->timebase = (float)devc->timebases[idx][0] / devc->timebases[idx][1];
g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
devc->timebase);
ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
break;
case SR_CONF_TRIGGER_SOURCE:
tmp_str = g_variant_get_string(data, NULL);
for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
if (!strcmp(trigger_sources[i], tmp_str)) {
g_free(devc->trigger_source);
devc->trigger_source = g_strdup(trigger_sources[i]);
if (!strcmp(devc->trigger_source, "AC Line"))
tmp_str = "ACL";
else if (!strcmp(devc->trigger_source, "CH1"))
tmp_str = "CHAN1";
else if (!strcmp(devc->trigger_source, "CH2"))
tmp_str = "CHAN2";
else if (!strcmp(devc->trigger_source, "CH3"))
tmp_str = "CHAN3";
else if (!strcmp(devc->trigger_source, "CH4"))
tmp_str = "CHAN4";
else
tmp_str = (char *)devc->trigger_source;
ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
break;
}
}
if (i == ARRAY_SIZE(trigger_sources)) {
sr_err("Invalid trigger source index: %d.", i);
ret = SR_ERR_ARG;
}
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_sources))) < 0)
return SR_ERR_ARG;
g_free(devc->trigger_source);
devc->trigger_source = g_strdup(trigger_sources[idx]);
if (!strcmp(devc->trigger_source, "AC Line"))
tmp_str = "ACL";
else if (!strcmp(devc->trigger_source, "CH1"))
tmp_str = "CHAN1";
else if (!strcmp(devc->trigger_source, "CH2"))
tmp_str = "CHAN2";
else if (!strcmp(devc->trigger_source, "CH3"))
tmp_str = "CHAN3";
else if (!strcmp(devc->trigger_source, "CH4"))
tmp_str = "CHAN4";
else
tmp_str = (char *)devc->trigger_source;
ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
break;
case SR_CONF_VDIV:
if (!cg)
return SR_ERR_CHANNEL_GROUP;
g_variant_get(data, "(tt)", &p, &q);
for (i = 0; i < devc->model->analog_channels; i++) {
if (cg == devc->analog_groups[i]) {
for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
if (vdivs[j][0] != p || vdivs[j][1] != q)
continue;
devc->vdiv[i] = (float)p / q;
g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
devc->vdiv[i]);
return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
buffer);
}
sr_err("Invalid vdiv index: %d.", j);
if (cg != devc->analog_groups[i])
continue;
if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(vdivs))) < 0)
return SR_ERR_ARG;
}
devc->vdiv[i] = (float)vdivs[idx][0] / vdivs[idx][1];
g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
devc->vdiv[i]);
return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
buffer);
}
sr_dbg("Didn't set vdiv, unknown channel(group).");
return SR_ERR_NA;
case SR_CONF_COUPLING:
if (!cg)
return SR_ERR_CHANNEL_GROUP;
tmp_str = g_variant_get_string(data, NULL);
for (i = 0; i < devc->model->analog_channels; i++) {
if (cg == devc->analog_groups[i]) {
for (j = 0; j < ARRAY_SIZE(coupling); j++) {
if (!strcmp(tmp_str, coupling[j])) {
g_free(devc->coupling[i]);
devc->coupling[i] = g_strdup(coupling[j]);
return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
devc->coupling[i]);
}
}
sr_err("Invalid coupling index: %d.", j);
if (cg != devc->analog_groups[i])
continue;
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(coupling))) < 0)
return SR_ERR_ARG;
}
g_free(devc->coupling[i]);
devc->coupling[i] = g_strdup(coupling[idx]);
return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
devc->coupling[i]);
}
sr_dbg("Didn't set coupling, unknown channel(group).");
return SR_ERR_NA;
@ -759,20 +727,16 @@ static int config_set(uint32_t key, GVariant *data,
return SR_ERR_CHANNEL_GROUP;
p = g_variant_get_uint64(data);
for (i = 0; i < devc->model->analog_channels; i++) {
if (cg == devc->analog_groups[i]) {
for (j = 0; j < ARRAY_SIZE(probe_factor); j++) {
if (p == probe_factor[j]) {
devc->attenuation[i] = p;
ret = rigol_ds_config_set(sdi, ":CHAN%d:PROB %"PRIu64,
i + 1, p);
if (ret == SR_OK)
rigol_ds_get_dev_cfg_vertical(sdi);
return ret;
}
}
sr_err("Invalid probe factor: %"PRIu64".", p);
if (cg != devc->analog_groups[i])
continue;
if ((idx = std_u64_idx(data, ARRAY_AND_SIZE(probe_factor))) < 0)
return SR_ERR_ARG;
}
devc->attenuation[i] = probe_factor[idx];
ret = rigol_ds_config_set(sdi, ":CHAN%d:PROB %"PRIu64,
i + 1, p);
if (ret == SR_OK)
rigol_ds_get_dev_cfg_vertical(sdi);
return ret;
}
sr_dbg("Didn't set probe factor, unknown channel(group).");
return SR_ERR_NA;

View File

@ -457,9 +457,7 @@ static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc;
gdouble low, high;
int ret;
unsigned int i;
int ret, idx;
(void)cg;
@ -478,17 +476,9 @@ static int config_set(uint32_t key, GVariant *data,
ret = (devc->capture_ratio > 100) ? SR_ERR : SR_OK;
break;
case SR_CONF_VOLTAGE_THRESHOLD:
g_variant_get(data, "(dd)", &low, &high);
ret = SR_ERR_ARG;
for (i = 0; i < ARRAY_SIZE(volt_thresholds); i++) {
if (fabs(volt_thresholds[i][0] - low) < 0.1 &&
fabs(volt_thresholds[i][1] - high) < 0.1) {
devc->selected_voltage_range =
volt_thresholds_ranges[i].range;
ret = SR_OK;
break;
}
}
if ((idx = std_double_tuple_idx(data, ARRAY_AND_SIZE(volt_thresholds))) < 0)
return SR_ERR_ARG;
devc->selected_voltage_range = volt_thresholds_ranges[idx].range;
break;
default:
ret = SR_ERR_NA;

View File

@ -41,12 +41,12 @@ static const int32_t trigger_matches[] = {
SR_TRIGGER_FALLING,
};
static const char *const trigger_source_names[] = {
static const char *trigger_source_names[] = {
[TRIGGER_CHANNELS] = "CH",
[TRIGGER_EXT_TRG] = "TRG",
};
static const char *const signal_edge_names[] = {
static const char *signal_edge_names[] = {
[EDGE_POSITIVE] = "r",
[EDGE_NEGATIVE] = "f",
};
@ -382,27 +382,6 @@ static int config_get(uint32_t key, GVariant **data,
return SR_OK;
}
/* Helper for mapping a string-typed configuration value to an index
* within a table of possible values.
*/
static int lookup_index(GVariant *value, const char *const *table, int len)
{
const char *entry;
int i;
entry = g_variant_get_string(value, NULL);
if (!entry)
return -1;
/* Linear search is fine for very small tables. */
for (i = 0; i < len; i++) {
if (strcmp(entry, table[i]) == 0)
return i;
}
return -1;
}
static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
@ -448,20 +427,17 @@ static int config_set(uint32_t key, GVariant *data,
? CLOCK_EXT_CLK : CLOCK_INTERNAL;
break;
case SR_CONF_CLOCK_EDGE:
idx = lookup_index(data, ARRAY_AND_SIZE(signal_edge_names));
if (idx < 0)
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(signal_edge_names))) < 0)
return SR_ERR_ARG;
devc->cfg_clock_edge = idx;
break;
case SR_CONF_TRIGGER_SOURCE:
idx = lookup_index(data, ARRAY_AND_SIZE(trigger_source_names));
if (idx < 0)
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_source_names))) < 0)
return SR_ERR_ARG;
devc->cfg_trigger_source = idx;
break;
case SR_CONF_TRIGGER_SLOPE:
idx = lookup_index(data, ARRAY_AND_SIZE(signal_edge_names));
if (idx < 0)
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(signal_edge_names))) < 0)
return SR_ERR_ARG;
devc->cfg_trigger_slope = idx;
break;

View File

@ -178,7 +178,7 @@ static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc;
const char *tmp_str;
int idx;
(void)cg;
@ -189,13 +189,9 @@ static int config_set(uint32_t key, GVariant *data,
devc->limit_samples = g_variant_get_uint64(data);
break;
case SR_CONF_DATA_SOURCE:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "Live"))
devc->data_source = DATA_SOURCE_LIVE;
else if (!strcmp(tmp_str, "Memory"))
devc->data_source = DATA_SOURCE_MEMORY;
else
return SR_ERR;
if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
return SR_ERR_ARG;
devc->data_source = idx;
break;
default:
return SR_ERR_NA;

View File

@ -282,14 +282,13 @@ static int config_get(uint32_t key, GVariant **data,
static int config_set(uint32_t key, GVariant *data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
int ret, cg_type;
int ret, cg_type, idx;
unsigned int i, j;
char float_str[30];
struct dev_context *devc;
const struct scope_config *model;
struct scope_state *state;
const char *tmp;
uint64_t p, q;
double tmp_d;
gboolean update_sample_rate;
@ -324,44 +323,29 @@ static int config_set(uint32_t key, GVariant *data,
case SR_CONF_VDIV:
if (cg_type == CG_NONE)
return SR_ERR_CHANNEL_GROUP;
g_variant_get(data, "(tt)", &p, &q);
for (i = 0; i < ARRAY_SIZE(dlm_vdivs); i++) {
if (p != dlm_vdivs[i][0] ||
q != dlm_vdivs[i][1])
if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(dlm_vdivs))) < 0)
return SR_ERR_ARG;
for (j = 1; j <= model->analog_channels; j++) {
if (cg != devc->analog_groups[j - 1])
continue;
for (j = 1; j <= model->analog_channels; j++) {
if (cg != devc->analog_groups[j - 1])
continue;
state->analog_states[j - 1].vdiv = i;
g_ascii_formatd(float_str, sizeof(float_str),
"%E", (float) p / q);
if (dlm_analog_chan_vdiv_set(sdi->conn, j, float_str) != SR_OK ||
sr_scpi_get_opc(sdi->conn) != SR_OK)
return SR_ERR;
break;
}
ret = SR_OK;
state->analog_states[j - 1].vdiv = idx;
g_ascii_formatd(float_str, sizeof(float_str),
"%E", (float) dlm_vdivs[idx][0] / dlm_vdivs[idx][1]);
if (dlm_analog_chan_vdiv_set(sdi->conn, j, float_str) != SR_OK ||
sr_scpi_get_opc(sdi->conn) != SR_OK)
return SR_ERR;
break;
}
ret = SR_OK;
break;
case SR_CONF_TIMEBASE:
g_variant_get(data, "(tt)", &p, &q);
for (i = 0; i < ARRAY_SIZE(dlm_timebases); i++) {
if (p != dlm_timebases[i][0] ||
q != dlm_timebases[i][1])
continue;
state->timebase = i;
g_ascii_formatd(float_str, sizeof(float_str),
"%E", (float) p / q);
ret = dlm_timebase_set(sdi->conn, float_str);
update_sample_rate = TRUE;
break;
}
if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(dlm_timebases))) < 0)
return SR_ERR_ARG;
state->timebase = idx;
g_ascii_formatd(float_str, sizeof(float_str),
"%E", (float) dlm_timebases[idx][0] / dlm_timebases[idx][1]);
ret = dlm_timebase_set(sdi->conn, float_str);
update_sample_rate = TRUE;
break;
case SR_CONF_HORIZ_TRIGGERPOS:
tmp_d = g_variant_get_double(data);

View File

@ -973,6 +973,17 @@ SR_PRIV GVariant *std_gvar_array_u64(const uint64_t *a, unsigned int n);
SR_PRIV GVariant *std_gvar_thresholds(const double a[][2], unsigned int n);
SR_PRIV int std_str_idx(GVariant *data, const char *a[], unsigned int n);
SR_PRIV int std_u64_idx(GVariant *data, const uint64_t a[], unsigned int n);
SR_PRIV int std_u8_idx(GVariant *data, const uint8_t a[], unsigned int n);
SR_PRIV int std_str_idx_s(const char *s, const char *a[], unsigned int n);
SR_PRIV int std_u8_idx_s(uint8_t b, const uint8_t a[], unsigned int n);
SR_PRIV int std_u64_tuple_idx(GVariant *data, const uint64_t a[][2], unsigned int n);
SR_PRIV int std_double_tuple_idx(GVariant *data, const double a[][2], unsigned int n);
SR_PRIV int std_double_tuple_idx_d0(const double d, const double a[][2], unsigned int n);
/*--- resource.c ------------------------------------------------------------*/
SR_PRIV int64_t sr_file_get_size(FILE *file);

126
src/std.c
View File

@ -26,6 +26,8 @@
*/
#include <config.h>
#include <string.h>
#include <math.h>
#include <glib.h>
#include <libsigrok/libsigrok.h>
#include "libsigrok-internal.h"
@ -702,3 +704,127 @@ SR_PRIV GVariant *std_gvar_thresholds(const double a[][2], unsigned int n)
return g_variant_builder_end(&gvb);
}
/* Return the index of 'data' in the array 'arr' (or -1). */
static int find_in_array(GVariant *data, const GVariantType *type,
const void *arr, unsigned int n)
{
const char * const *sarr;
const char *s;
const uint64_t *u64arr;
const uint8_t *u8arr;
uint64_t u64;
uint8_t u8;
unsigned int i;
if (!g_variant_is_of_type(data, type))
return -1;
switch (g_variant_classify(data)) {
case G_VARIANT_CLASS_STRING:
s = g_variant_get_string(data, NULL);
sarr = arr;
for (i = 0; i < n; i++)
if (!strcmp(s, sarr[i]))
return i;
break;
case G_VARIANT_CLASS_UINT64:
u64 = g_variant_get_uint64(data);
u64arr = arr;
for (i = 0; i < n; i++)
if (u64 == u64arr[i])
return i;
break;
case G_VARIANT_CLASS_BYTE:
u8 = g_variant_get_byte(data);
u8arr = arr;
for (i = 0; i < n; i++)
if (u8 == u8arr[i])
return i;
default:
break;
}
return -1;
}
SR_PRIV int std_str_idx(GVariant *data, const char *a[], unsigned int n)
{
return find_in_array(data, G_VARIANT_TYPE_STRING, a, n);
}
SR_PRIV int std_u64_idx(GVariant *data, const uint64_t a[], unsigned int n)
{
return find_in_array(data, G_VARIANT_TYPE_UINT64, a, n);
}
SR_PRIV int std_u8_idx(GVariant *data, const uint8_t a[], unsigned int n)
{
return find_in_array(data, G_VARIANT_TYPE_BYTE, a, n);
}
SR_PRIV int std_str_idx_s(const char *s, const char *a[], unsigned int n)
{
int idx;
GVariant *data;
data = g_variant_new_string(s);
idx = find_in_array(data, G_VARIANT_TYPE_STRING, a, n);
g_variant_unref(data);
return idx;
}
SR_PRIV int std_u8_idx_s(uint8_t b, const uint8_t a[], unsigned int n)
{
int idx;
GVariant *data;
data = g_variant_new_byte(b);
idx = find_in_array(data, G_VARIANT_TYPE_BYTE, a, n);
g_variant_unref(data);
return idx;
}
SR_PRIV int std_u64_tuple_idx(GVariant *data, const uint64_t a[][2], unsigned int n)
{
unsigned int i;
uint64_t low, high;
g_variant_get(data, "(tt)", &low, &high);
for (i = 0; i < n; i++)
if (a[i][0] == low && a[i][1] == high)
return i;
return -1;
}
SR_PRIV int std_double_tuple_idx(GVariant *data, const double a[][2], unsigned int n)
{
unsigned int i;
double low, high;
g_variant_get(data, "(dd)", &low, &high);
for (i = 0; i < n; i++)
if ((fabs(a[i][0] - low) < 0.1) && ((fabs(a[i][1] - high) < 0.1)))
return i;
return -1;
}
SR_PRIV int std_double_tuple_idx_d0(const double d, const double a[][2], unsigned int n)
{
unsigned int i;
for (i = 0; i < n; i++)
if (d == a[i][0])
return i;
return -1;
}