cem-dt-885x: Support for sound pressure level measurement range

This commit is contained in:
Bert Vermeulen 2013-06-17 01:26:25 +02:00
parent 8417ebad12
commit f157b2eebb
3 changed files with 144 additions and 5 deletions

View File

@ -37,6 +37,7 @@ static const int32_t hwcaps[] = {
SR_CONF_SPL_WEIGHT_TIME,
SR_CONF_HOLD_MAX,
SR_CONF_HOLD_MIN,
SR_CONF_SPL_MEASUREMENT_RANGE,
};
static const char *weight_freq[] = {
@ -49,6 +50,13 @@ static const char *weight_time[] = {
"S",
};
static const uint64_t meas_ranges[][2] = {
{ 30, 130 },
{ 30, 80 },
{ 50, 100 },
{ 80, 130 },
};
SR_PRIV struct sr_dev_driver cem_dt_885x_driver_info;
static struct sr_dev_driver *di = &cem_dt_885x_driver_info;
@ -102,6 +110,7 @@ static GSList *scan(GSList *options)
}
devc->cur_mqflags = 0;
devc->recording = -1;
devc->cur_meas_range = 0;
if (!(sdi->conn = sr_serial_dev_inst_new(conn, SERIALCOMM)))
return NULL;
@ -173,6 +182,8 @@ static int cleanup(void)
static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
GVariant *range[2];
uint64_t low, high;
int tmp, ret;
if (!sdi)
@ -214,6 +225,13 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi)
if ((ret = cem_dt_885x_holdmode_get(sdi, &tmp)) == SR_OK)
*data = g_variant_new_boolean(tmp == SR_MQFLAG_MIN);
break;
case SR_CONF_SPL_MEASUREMENT_RANGE:
if ((ret = cem_dt_885x_meas_range_get(sdi, &low, &high)) == SR_OK) {
range[0] = g_variant_new_uint64(low);
range[1] = g_variant_new_uint64(high);
*data = g_variant_new_tuple(range, 2);
}
break;
default:
return SR_ERR_NA;
}
@ -224,7 +242,8 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi)
static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
uint64_t tmp_u64;
uint64_t tmp_u64, low, high;
unsigned int i;
int tmp, ret;
const char *tmp_str;
@ -276,6 +295,16 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi)
tmp = g_variant_get_boolean(data) ? SR_MQFLAG_MIN : 0;
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;
default:
ret = SR_ERR_NA;
}
@ -285,6 +314,9 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi)
static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
{
GVariant *tuple, *range[2];
GVariantBuilder gvb;
unsigned int i;
int ret;
(void)sdi;
@ -305,6 +337,16 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
case SR_CONF_SPL_WEIGHT_TIME:
*data = g_variant_new_strv(weight_time, ARRAY_SIZE(weight_time));
break;
case SR_CONF_SPL_MEASUREMENT_RANGE:
g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
for (i = 0; i < ARRAY_SIZE(meas_ranges); i++) {
range[0] = g_variant_new_uint64(meas_ranges[i][0]);
range[1] = g_variant_new_uint64(meas_ranges[i][1]);
tuple = g_variant_new_tuple(range, 2);
g_variant_builder_add_value(&gvb, tuple);
}
*data = g_variant_builder_end(&gvb);
break;
default:
return SR_ERR_NA;
}

View File

@ -152,6 +152,12 @@ static void process_mset(const struct sr_dev_inst *sdi)
case TOKEN_RECORDING_OFF:
devc->recording = FALSE;
break;
case TOKEN_MEAS_RANGE_30_80:
case TOKEN_MEAS_RANGE_30_130:
case TOKEN_MEAS_RANGE_50_100:
case TOKEN_MEAS_RANGE_80_130:
devc->cur_meas_range = devc->token;
break;
case TOKEN_TIME:
case TOKEN_STORE_OK:
case TOKEN_STORE_FULL:
@ -160,10 +166,6 @@ static void process_mset(const struct sr_dev_inst *sdi)
case TOKEN_MEAS_RANGE_OK:
case TOKEN_MEAS_RANGE_OVER:
case TOKEN_MEAS_RANGE_UNDER:
case TOKEN_MEAS_RANGE_30_80:
case TOKEN_MEAS_RANGE_30_130:
case TOKEN_MEAS_RANGE_50_100:
case TOKEN_MEAS_RANGE_80_130:
/* Not useful, or not expressable in sigrok. */
break;
}
@ -594,3 +596,92 @@ SR_PRIV int cem_dt_885x_holdmode_set(const struct sr_dev_inst *sdi, int holdmode
return ret;
}
SR_PRIV int cem_dt_885x_meas_range_get(const struct sr_dev_inst *sdi,
uint64_t *low, uint64_t *high)
{
struct dev_context *devc;
char tokens[5];
devc = sdi->priv;
if (devc->cur_meas_range == 0) {
tokens[0] = TOKEN_MEAS_RANGE_30_130;
tokens[1] = TOKEN_MEAS_RANGE_30_80;
tokens[2] = TOKEN_MEAS_RANGE_50_100;
tokens[3] = TOKEN_MEAS_RANGE_80_130;
tokens[4] = -1;
if (wait_for_token(sdi, tokens, 0) != SR_OK)
return SR_ERR;
devc->cur_meas_range = devc->token;
}
switch (devc->cur_meas_range) {
case TOKEN_MEAS_RANGE_30_130:
*low = 30;
*high = 130;
break;
case TOKEN_MEAS_RANGE_30_80:
*low = 30;
*high = 80;
break;
case TOKEN_MEAS_RANGE_50_100:
*low = 50;
*high = 100;
break;
case TOKEN_MEAS_RANGE_80_130:
*low = 80;
*high = 130;
break;
default:
return SR_ERR;
}
return SR_OK;
}
SR_PRIV int cem_dt_885x_meas_range_set(const struct sr_dev_inst *sdi,
uint64_t low, uint64_t high)
{
struct dev_context *devc;
int ret;
char token, tokens[6];
devc = sdi->priv;
if (low == 30 && high == 130)
token = TOKEN_MEAS_RANGE_30_130;
else if (low == 30 && high == 80)
token = TOKEN_MEAS_RANGE_30_80;
else if (low == 50 && high == 100)
token = TOKEN_MEAS_RANGE_50_100;
else if (low == 80 && high == 130)
token = TOKEN_MEAS_RANGE_80_130;
else
return SR_ERR;
sr_dbg("want 0x%.2x", token);
/* The toggle below needs the desired state in first position. */
tokens[0] = token;
tokens[1] = TOKEN_MEAS_RANGE_30_130;
tokens[2] = TOKEN_MEAS_RANGE_30_80;
tokens[3] = TOKEN_MEAS_RANGE_50_100;
tokens[4] = TOKEN_MEAS_RANGE_80_130;
tokens[5] = -1;
if (devc->cur_meas_range == 0) {
/* 110ms should be enough for two of these announcements */
if (wait_for_token(sdi, tokens, 110) != SR_OK)
return SR_ERR;
devc->cur_meas_range = devc->token;
}
if (devc->cur_meas_range == token)
/* Already set to this range. */
return SR_OK;
/* For measurement range, it works best to ignore announcements of the
* current setting and keep resending the toggle quickly. */
tokens[1] = -1;
ret = cem_dt_885x_toggle(sdi, CMD_TOGGLE_MEAS_RANGE, tokens, 11);
return ret;
}

View File

@ -71,6 +71,7 @@ enum {
CMD_TOGGLE_WEIGHT_FREQ = 0x99,
CMD_TOGGLE_WEIGHT_TIME = 0x77,
CMD_TOGGLE_HOLD_MAX_MIN = 0x11,
CMD_TOGGLE_MEAS_RANGE = 0x88,
};
/** Private, per-device-instance driver context. */
@ -78,6 +79,7 @@ struct dev_context {
/* Device state */
uint64_t cur_mqflags;
int recording;
int cur_meas_range;
/* Acquisition settings */
uint64_t limit_samples;
@ -115,5 +117,9 @@ SR_PRIV int cem_dt_885x_weight_time_set(const struct sr_dev_inst *sdi, int timew
SR_PRIV int cem_dt_885x_holdmode_get(const struct sr_dev_inst *sdi,
gboolean *holdmode);
SR_PRIV int cem_dt_885x_holdmode_set(const struct sr_dev_inst *sdi, int holdmode);
SR_PRIV int cem_dt_885x_meas_range_get(const struct sr_dev_inst *sdi,
uint64_t *low, uint64_t *high);
SR_PRIV int cem_dt_885x_meas_range_set(const struct sr_dev_inst *sdi,
uint64_t low, uint64_t high);
#endif