SR_CONF_SPL_WEIGHT_TIME,
SR_CONF_HOLD_MAX,
SR_CONF_HOLD_MIN,
+ SR_CONF_SPL_MEASUREMENT_RANGE,
};
static const char *weight_freq[] = {
"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;
}
devc->cur_mqflags = 0;
devc->recording = -1;
+ devc->cur_meas_range = 0;
if (!(sdi->conn = sr_serial_dev_inst_new(conn, SERIALCOMM)))
return NULL;
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)
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;
}
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;
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;
}
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;
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;
}
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:
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;
}
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;
+}
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. */
/* Device state */
uint64_t cur_mqflags;
int recording;
+ int cur_meas_range;
/* Acquisition settings */
uint64_t limit_samples;
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