static int recv_fetc(const struct sr_dev_inst *sdi, GMatchInfo *match) { struct dev_context *devc; struct sr_datafeed_packet packet; struct sr_datafeed_analog_old analog; float fvalue; const char *s; char *mstr; sr_spew("FETC reply '%s'.", g_match_info_get_string(match)); devc = sdi->priv; if (devc->cur_mq == -1) /* Haven't seen configuration yet, so can't know what * the fetched float means. Not really an error, we'll * get metadata soon enough. */ return SR_OK; s = g_match_info_get_string(match); if (!strcmp(s, "-9.90000000E+37") || !strcmp(s, "+9.90000000E+37")) { /* An invalid measurement shows up on the display as "O.L", but * comes through like this. Since comparing 38-digit floats * is rather problematic, we'll cut through this here. */ fvalue = NAN; } else { mstr = g_match_info_fetch(match, 1); if (sr_atof_ascii(mstr, &fvalue) != SR_OK) { g_free(mstr); sr_dbg("Invalid float."); return SR_ERR; } g_free(mstr); if (devc->cur_divider > 0) fvalue /= devc->cur_divider; } memset(&analog, 0, sizeof(struct sr_datafeed_analog_old)); analog.mq = devc->cur_mq; analog.unit = devc->cur_unit; analog.mqflags = devc->cur_mqflags; analog.channels = sdi->channels; analog.num_samples = 1; analog.data = &fvalue; packet.type = SR_DF_ANALOG_OLD; packet.payload = &analog; sr_session_send(devc->cb_data, &packet); devc->num_samples++; return SR_OK; }
/* This comes in whenever the rotary switch is changed to a new position. * We could use it to determine the major measurement mode, but we already * have the output of CONF? for that, which is more detailed. However * we do need to catch this here, or it'll show up in some other output. */ static int recv_switch(const struct sr_dev_inst *sdi, GMatchInfo *match) { (void)sdi; sr_spew("Switch '%s'.", g_match_info_get_string(match)); return SR_OK; }
/* This comes in whenever the rotary switch is changed to a new position. * We could use it to determine the major measurement mode, but we already * have the output of CONF? for that, which is more detailed. However * we do need to catch this here, or it'll show up in some other output. */ static int recv_switch(const struct sr_dev_inst *sdi, GMatchInfo *match) { struct dev_context *devc = sdi->priv; sr_spew("Switch '%s'.", g_match_info_get_string(match)); devc->current_job = 0; devc->job_running = FALSE; memset(devc->jobs_start, 0, sizeof(devc->jobs_start)); devc->cur_mq[0] = -1; if (devc->profile->nb_channels > 2) devc->cur_mq[1] = -1; return SR_OK; }
static gboolean replace_by_id (const GMatchInfo *match_info, GString *expanded_regex, gpointer user_data) { gchar *id, *subst, *escapes; gchar *tmp; GError *tmp_error = NULL; struct ReplaceByIdData *data = user_data; escapes = g_match_info_fetch (match_info, 1); tmp = g_match_info_fetch (match_info, 2); g_strstrip (tmp); if (id_is_decorated (tmp, NULL)) id = g_strdup (tmp); else id = decorate_id (data->parser_state, tmp); g_free (tmp); subst = g_hash_table_lookup (data->parser_state->defined_regexes, id); if (subst == NULL) g_set_error (&tmp_error, PARSER_ERROR, PARSER_ERROR_WRONG_ID, _("Unknown id '%s' in regex '%s'"), id, g_match_info_get_string (match_info)); if (tmp_error == NULL) { g_string_append (expanded_regex, escapes); g_string_append (expanded_regex, subst); } g_free (escapes); g_free (id); if (tmp_error != NULL) { g_propagate_error (&data->error, tmp_error); return TRUE; } return FALSE; }
static int recv_conf(const struct sr_dev_inst *sdi, GMatchInfo *match) { struct dev_context *devc; char *mstr; sr_spew("CONF? response '%s'.", g_match_info_get_string(match)); devc = sdi->priv; mstr = g_match_info_fetch(match, 1); if (!strcmp(mstr, "DIOD")) { devc->cur_mq = SR_MQ_VOLTAGE; devc->cur_unit = SR_UNIT_VOLT; devc->cur_mqflags = SR_MQFLAG_DIODE; devc->cur_divider = 0; } else sr_dbg("Unknown single argument."); g_free(mstr); return SR_OK; }
static int recv_conf_u124x_5x(const struct sr_dev_inst *sdi, GMatchInfo *match) { struct dev_context *devc; char *mstr, *m2; sr_spew("CONF? response '%s'.", g_match_info_get_string(match)); devc = sdi->priv; mstr = g_match_info_fetch(match, 1); if (!strncmp(mstr, "VOLT", 4)) { devc->cur_mq = SR_MQ_VOLTAGE; devc->cur_unit = SR_UNIT_VOLT; devc->cur_mqflags = 0; devc->cur_divider = 0; if (mstr[4] == ':') { if (!strncmp(mstr + 5, "AC", 2)) { devc->cur_mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS; } else if (!strncmp(mstr + 5, "DC", 2)) { devc->cur_mqflags |= SR_MQFLAG_DC; } else if (!strncmp(mstr + 5, "ACDC", 4)) { /* AC + DC offset */ devc->cur_mqflags |= SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS; } else { devc->cur_mqflags &= ~(SR_MQFLAG_AC | SR_MQFLAG_DC); } } else devc->cur_mqflags &= ~(SR_MQFLAG_AC | SR_MQFLAG_DC); } else if (!strcmp(mstr, "CURR")) { devc->cur_mq = SR_MQ_CURRENT; devc->cur_unit = SR_UNIT_AMPERE; devc->cur_mqflags = 0; devc->cur_divider = 0; } else if (!strcmp(mstr, "RES")) { devc->cur_mq = SR_MQ_RESISTANCE; devc->cur_unit = SR_UNIT_OHM; devc->cur_mqflags = 0; devc->cur_divider = 0; } else if (!strcmp(mstr, "CAP")) { devc->cur_mq = SR_MQ_CAPACITANCE; devc->cur_unit = SR_UNIT_FARAD; devc->cur_mqflags = 0; devc->cur_divider = 0; } else if (!strcmp(mstr, "FREQ")) { devc->cur_mq = SR_MQ_FREQUENCY; devc->cur_unit = SR_UNIT_HERTZ; devc->cur_mqflags = 0; devc->cur_divider = 0; } else if (!strcmp(mstr, "CONT")) { devc->cur_mq = SR_MQ_CONTINUITY; devc->cur_unit = SR_UNIT_BOOLEAN; devc->cur_mqflags = 0; devc->cur_divider = 0; } else if (!strncmp(mstr, "T1", 2) || !strncmp(mstr, "T2", 2)) { devc->cur_mq = SR_MQ_TEMPERATURE; m2 = g_match_info_fetch(match, 2); if (!strcmp(m2, "FAR")) devc->cur_unit = SR_UNIT_FAHRENHEIT; else devc->cur_unit = SR_UNIT_CELSIUS; g_free(m2); devc->cur_mqflags = 0; devc->cur_divider = 0; } else if (!strcmp(mstr, "SCOU")) { /* * Switch counter, not supported. Not sure what values * come from FETC in this mode, or how they would map * into libsigrok. */ } else if (!strncmp(mstr, "CPER:", 5)) { devc->cur_mq = SR_MQ_CURRENT; devc->cur_unit = SR_UNIT_PERCENTAGE; devc->cur_mqflags = 0; devc->cur_divider = 0; } else { sr_dbg("Unknown first argument '%s'.", mstr); } g_free(mstr); return SR_OK; }
static int recv_conf_u123x(const struct sr_dev_inst *sdi, GMatchInfo *match) { struct dev_context *devc; char *mstr; sr_spew("CONF? response '%s'.", g_match_info_get_string(match)); devc = sdi->priv; mstr = g_match_info_fetch(match, 1); if (!strcmp(mstr, "V")) { devc->cur_mq = SR_MQ_VOLTAGE; devc->cur_unit = SR_UNIT_VOLT; devc->cur_mqflags = 0; devc->cur_divider = 0; } else if (!strcmp(mstr, "MV")) { if (devc->mode_tempaux) { devc->cur_mq = SR_MQ_TEMPERATURE; /* No way to detect whether Fahrenheit or Celsius * is used, so we'll just default to Celsius. */ devc->cur_unit = SR_UNIT_CELSIUS; devc->cur_mqflags = 0; devc->cur_divider = 0; } else { devc->cur_mq = SR_MQ_VOLTAGE; devc->cur_unit = SR_UNIT_VOLT; devc->cur_mqflags = 0; devc->cur_divider = 1000; } } else if (!strcmp(mstr, "A")) { devc->cur_mq = SR_MQ_CURRENT; devc->cur_unit = SR_UNIT_AMPERE; devc->cur_mqflags = 0; devc->cur_divider = 0; } else if (!strcmp(mstr, "UA")) { devc->cur_mq = SR_MQ_CURRENT; devc->cur_unit = SR_UNIT_AMPERE; devc->cur_mqflags = 0; devc->cur_divider = 1000000; } else if (!strcmp(mstr, "FREQ")) { devc->cur_mq = SR_MQ_FREQUENCY; devc->cur_unit = SR_UNIT_HERTZ; devc->cur_mqflags = 0; devc->cur_divider = 0; } else if (!strcmp(mstr, "RES")) { if (devc->mode_continuity) { devc->cur_mq = SR_MQ_CONTINUITY; devc->cur_unit = SR_UNIT_BOOLEAN; } else { devc->cur_mq = SR_MQ_RESISTANCE; devc->cur_unit = SR_UNIT_OHM; } devc->cur_mqflags = 0; devc->cur_divider = 0; } else if (!strcmp(mstr, "CAP")) { devc->cur_mq = SR_MQ_CAPACITANCE; devc->cur_unit = SR_UNIT_FARAD; devc->cur_mqflags = 0; devc->cur_divider = 0; } else sr_dbg("Unknown first argument."); g_free(mstr); if (g_match_info_get_match_count(match) == 4) { mstr = g_match_info_fetch(match, 3); /* Third value, if present, is always AC or DC. */ if (!strcmp(mstr, "AC")) { devc->cur_mqflags |= SR_MQFLAG_AC; if (devc->cur_mq == SR_MQ_VOLTAGE) devc->cur_mqflags |= SR_MQFLAG_RMS; } else if (!strcmp(mstr, "DC")) { devc->cur_mqflags |= SR_MQFLAG_DC; } else { sr_dbg("Unknown first argument '%s'.", mstr); } g_free(mstr); } else devc->cur_mqflags &= ~(SR_MQFLAG_AC | SR_MQFLAG_DC); return SR_OK; }
static int recv_log(const struct sr_dev_inst *sdi, GMatchInfo *match, const int mqs[], const int units[], const int exponents[], unsigned int num_functions) { struct dev_context *devc; struct sr_datafeed_packet packet; struct sr_datafeed_analog analog; struct sr_analog_encoding encoding; struct sr_analog_meaning meaning; struct sr_analog_spec spec; char *mstr; unsigned function; int value, negative, overload, exponent, alternate_unit, mq, unit; int mqflags = 0; float fvalue; sr_spew("LOG response '%s'.", g_match_info_get_string(match)); devc = sdi->priv; mstr = g_match_info_fetch(match, 2); if (sr_atoi(mstr, (int*)&function) != SR_OK || function >= num_functions) { g_free(mstr); sr_dbg("Invalid function."); return SR_ERR; } g_free(mstr); mstr = g_match_info_fetch(match, 3); if (sr_atoi(mstr, &value) != SR_OK) { g_free(mstr); sr_dbg("Invalid value."); return SR_ERR; } g_free(mstr); mstr = g_match_info_fetch(match, 1); negative = mstr[7] & 2 ? -1 : 1; overload = mstr[8] & 4; exponent = (mstr[9] & 0xF) + exponents[function]; alternate_unit = mstr[10] & 1; if (mstr[ 8] & 1) mqflags |= SR_MQFLAG_DC; if (mstr[ 8] & 2) mqflags |= SR_MQFLAG_AC; if (mstr[11] & 4) mqflags |= SR_MQFLAG_RELATIVE; if (mstr[12] & 1) mqflags |= SR_MQFLAG_AVG; if (mstr[12] & 2) mqflags |= SR_MQFLAG_MIN; if (mstr[12] & 4) mqflags |= SR_MQFLAG_MAX; if (function == 5) mqflags |= SR_MQFLAG_DIODE | SR_MQFLAG_DC; g_free(mstr); mq = mqs[function]; unit = units[function]; if (alternate_unit) { if (mq == SR_MQ_RESISTANCE) mq = SR_MQ_CONTINUITY; if (unit == SR_UNIT_DECIBEL_MW) unit = SR_UNIT_DECIBEL_VOLT; if (unit == SR_UNIT_CELSIUS) { unit = SR_UNIT_FAHRENHEIT; if (devc->profile->model == KEYSIGHT_U1281 || devc->profile->model == KEYSIGHT_U1282) exponent--; } } if (overload) fvalue = NAN; else fvalue = negative * value * powf(10, exponent); sr_analog_init(&analog, &encoding, &meaning, &spec, -exponent); analog.meaning->mq = mq; analog.meaning->unit = unit; analog.meaning->mqflags = mqflags; analog.meaning->channels = g_slist_append(NULL, devc->cur_channel); analog.num_samples = 1; analog.data = &fvalue; packet.type = SR_DF_ANALOG; packet.payload = &analog; sr_session_send(sdi, &packet); g_slist_free(analog.meaning->channels); sr_sw_limits_update_samples_read(&devc->limits, 1); devc->cur_sample++; return JOB_LOG; }
static int recv_conf_u124x_5x(const struct sr_dev_inst *sdi, GMatchInfo *match) { struct dev_context *devc; char *mstr, *rstr, *m2; int i, resolution; sr_spew("CONF? response '%s'.", g_match_info_get_string(match)); devc = sdi->priv; i = devc->cur_conf->index; devc->mode_squarewave = 0; rstr = g_match_info_fetch(match, 4); if (rstr && sr_atoi(rstr, &resolution) == SR_OK) { devc->cur_digits[i] = -resolution; devc->cur_encoding[i] = -resolution + 1; } g_free(rstr); mstr = g_match_info_fetch(match, 1); if (!strncmp(mstr, "VOLT", 4)) { devc->cur_mq[i] = SR_MQ_VOLTAGE; devc->cur_unit[i] = SR_UNIT_VOLT; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; if (i == 0 && devc->mode_dbm_dbv) { devc->cur_unit[i] = devc->mode_dbm_dbv; devc->cur_digits[i] = 3; devc->cur_encoding[i] = 4; } if (mstr[4] == ':') { if (!strncmp(mstr + 5, "ACDC", 4)) { /* AC + DC offset */ devc->cur_mqflags[i] |= SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS; } else if (!strncmp(mstr + 5, "AC", 2)) { devc->cur_mqflags[i] |= SR_MQFLAG_AC | SR_MQFLAG_RMS; } else if (!strncmp(mstr + 5, "DC", 2)) { devc->cur_mqflags[i] |= SR_MQFLAG_DC; } else if (!strncmp(mstr + 5, "HRAT", 4)) { devc->cur_mq[i] = SR_MQ_HARMONIC_RATIO; devc->cur_unit[i] = SR_UNIT_PERCENTAGE; devc->cur_digits[i] = 2; devc->cur_encoding[i] = 3; } } else devc->cur_mqflags[i] |= SR_MQFLAG_DC; } else if (!strncmp(mstr, "CURR", 4)) { devc->cur_mq[i] = SR_MQ_CURRENT; devc->cur_unit[i] = SR_UNIT_AMPERE; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; if (mstr[4] == ':') { if (!strncmp(mstr + 5, "ACDC", 4)) { /* AC + DC offset */ devc->cur_mqflags[i] |= SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS; } else if (!strncmp(mstr + 5, "AC", 2)) { devc->cur_mqflags[i] |= SR_MQFLAG_AC | SR_MQFLAG_RMS; } else if (!strncmp(mstr + 5, "DC", 2)) { devc->cur_mqflags[i] |= SR_MQFLAG_DC; } } else devc->cur_mqflags[i] |= SR_MQFLAG_DC; } else if (!strcmp(mstr, "RES")) { devc->cur_mq[i] = SR_MQ_RESISTANCE; devc->cur_unit[i] = SR_UNIT_OHM; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; } else if (!strcmp(mstr, "COND")) { devc->cur_mq[i] = SR_MQ_CONDUCTANCE; devc->cur_unit[i] = SR_UNIT_SIEMENS; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; } else if (!strcmp(mstr, "CAP")) { devc->cur_mq[i] = SR_MQ_CAPACITANCE; devc->cur_unit[i] = SR_UNIT_FARAD; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; } else if (!strncmp(mstr, "FREQ", 4) || !strncmp(mstr, "FC1", 3)) { devc->cur_mq[i] = SR_MQ_FREQUENCY; devc->cur_unit[i] = SR_UNIT_HERTZ; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; } else if (!strncmp(mstr, "PULS:PWID", 9)) { devc->cur_mq[i] = SR_MQ_PULSE_WIDTH; devc->cur_unit[i] = SR_UNIT_SECOND; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; devc->cur_encoding[i] = MIN(devc->cur_encoding[i], 6); } else if (!strncmp(mstr, "PULS:PDUT", 9)) { devc->cur_mq[i] = SR_MQ_DUTY_CYCLE; devc->cur_unit[i] = SR_UNIT_PERCENTAGE; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; devc->cur_digits[i] = 3; devc->cur_encoding[i] = 4; } else if (!strcmp(mstr, "CONT")) { devc->cur_mq[i] = SR_MQ_CONTINUITY; devc->cur_unit[i] = SR_UNIT_OHM; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; } else if (!strcmp(mstr, "DIOD")) { devc->cur_mq[i] = SR_MQ_VOLTAGE; devc->cur_unit[i] = SR_UNIT_VOLT; devc->cur_mqflags[i] = SR_MQFLAG_DIODE | SR_MQFLAG_DC; devc->cur_exponent[i] = 0; if (devc->profile->model == KEYSIGHT_U1281 || devc->profile->model == KEYSIGHT_U1282) { devc->cur_digits[i] = 4; devc->cur_encoding[i] = 5; } else { devc->cur_digits[i] = 3; devc->cur_encoding[i] = 4; } } else if (!strncmp(mstr, "T1", 2) || !strncmp(mstr, "T2", 2) || !strncmp(mstr, "TEMP", 4)) { devc->cur_mq[i] = SR_MQ_TEMPERATURE; m2 = g_match_info_fetch(match, 2); if (!m2 && devc->profile->nb_channels == 3) /* * TEMP without param is for secondary display (channel P2) * and is identical to channel P3, so discard it. */ devc->cur_mq[i] = -1; else if (m2 && !strcmp(m2, "FAR")) devc->cur_unit[i] = SR_UNIT_FAHRENHEIT; else devc->cur_unit[i] = SR_UNIT_CELSIUS; g_free(m2); devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; devc->cur_digits[i] = 1; devc->cur_encoding[i] = 2; } else if (!strcmp(mstr, "SCOU")) { /* * Switch counter, not supported. Not sure what values * come from FETC in this mode, or how they would map * into libsigrok. */ } else if (!strncmp(mstr, "CPER:", 5)) { devc->cur_mq[i] = SR_MQ_CURRENT; devc->cur_unit[i] = SR_UNIT_PERCENTAGE; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; devc->cur_digits[i] = 2; devc->cur_encoding[i] = 3; } else if (!strcmp(mstr, "SQU")) { /* * Square wave output, not supported. FETC just return * an error in this mode, so don't even call it. */ devc->mode_squarewave = 1; } else if (!strcmp(mstr, "NCV")) { devc->cur_mq[i] = SR_MQ_VOLTAGE; devc->cur_unit[i] = SR_UNIT_VOLT; devc->cur_mqflags[i] = SR_MQFLAG_AC; if (devc->profile->model == KEYSIGHT_U1281 || devc->profile->model == KEYSIGHT_U1282) { devc->cur_exponent[i] = -3; devc->cur_digits[i] = -1; devc->cur_encoding[i] = 0; } else { devc->cur_exponent[i] = 0; devc->cur_digits[i] = 2; devc->cur_encoding[i] = 3; } } else { sr_dbg("Unknown first argument '%s'.", mstr); } g_free(mstr); struct sr_channel *prev_conf = devc->cur_conf; devc->cur_conf = sr_next_enabled_channel(sdi, devc->cur_conf); if (devc->cur_conf->index >= MIN(devc->profile->nb_channels, 2)) devc->cur_conf = sr_next_enabled_channel(sdi, devc->cur_conf); if (devc->cur_conf->index > prev_conf->index) return JOB_AGAIN; else return JOB_CONF; }
static int recv_conf_u123x(const struct sr_dev_inst *sdi, GMatchInfo *match) { struct dev_context *devc; char *mstr, *rstr; int i, resolution; sr_spew("CONF? response '%s'.", g_match_info_get_string(match)); devc = sdi->priv; i = devc->cur_conf->index; rstr = g_match_info_fetch(match, 2); if (rstr) sr_atoi(rstr, &resolution); g_free(rstr); mstr = g_match_info_fetch(match, 1); if (!strcmp(mstr, "V")) { devc->cur_mq[i] = SR_MQ_VOLTAGE; devc->cur_unit[i] = SR_UNIT_VOLT; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; devc->cur_digits[i] = 4 - resolution; } else if (!strcmp(mstr, "MV")) { if (devc->mode_tempaux) { devc->cur_mq[i] = SR_MQ_TEMPERATURE; /* No way to detect whether Fahrenheit or Celsius * is used, so we'll just default to Celsius. */ devc->cur_unit[i] = SR_UNIT_CELSIUS; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; devc->cur_digits[i] = 1; } else { devc->cur_mq[i] = SR_MQ_VOLTAGE; devc->cur_unit[i] = SR_UNIT_VOLT; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = -3; devc->cur_digits[i] = 5 - resolution; } } else if (!strcmp(mstr, "A")) { devc->cur_mq[i] = SR_MQ_CURRENT; devc->cur_unit[i] = SR_UNIT_AMPERE; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; devc->cur_digits[i] = 3 - resolution; } else if (!strcmp(mstr, "UA")) { devc->cur_mq[i] = SR_MQ_CURRENT; devc->cur_unit[i] = SR_UNIT_AMPERE; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = -6; devc->cur_digits[i] = 8 - resolution; } else if (!strcmp(mstr, "FREQ")) { devc->cur_mq[i] = SR_MQ_FREQUENCY; devc->cur_unit[i] = SR_UNIT_HERTZ; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; devc->cur_digits[i] = 2 - resolution; } else if (!strcmp(mstr, "RES")) { if (devc->mode_continuity) { devc->cur_mq[i] = SR_MQ_CONTINUITY; devc->cur_unit[i] = SR_UNIT_BOOLEAN; } else { devc->cur_mq[i] = SR_MQ_RESISTANCE; devc->cur_unit[i] = SR_UNIT_OHM; } devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; devc->cur_digits[i] = 1 - resolution; } else if (!strcmp(mstr, "DIOD")) { devc->cur_mq[i] = SR_MQ_VOLTAGE; devc->cur_unit[i] = SR_UNIT_VOLT; devc->cur_mqflags[i] = SR_MQFLAG_DIODE | SR_MQFLAG_DC; devc->cur_exponent[i] = 0; devc->cur_digits[i] = 3; } else if (!strcmp(mstr, "CAP")) { devc->cur_mq[i] = SR_MQ_CAPACITANCE; devc->cur_unit[i] = SR_UNIT_FARAD; devc->cur_mqflags[i] = 0; devc->cur_exponent[i] = 0; devc->cur_digits[i] = 9 - resolution; } else sr_dbg("Unknown first argument."); g_free(mstr); /* This is based on guess, supposing similarity with other models. */ devc->cur_encoding[i] = devc->cur_digits[i] + 1; if (g_match_info_get_match_count(match) == 4) { mstr = g_match_info_fetch(match, 3); /* Third value, if present, is always AC or DC. */ if (!strcmp(mstr, "AC")) { devc->cur_mqflags[i] |= SR_MQFLAG_AC; if (devc->cur_mq[i] == SR_MQ_VOLTAGE) devc->cur_mqflags[i] |= SR_MQFLAG_RMS; } else if (!strcmp(mstr, "DC")) { devc->cur_mqflags[i] |= SR_MQFLAG_DC; } else { sr_dbg("Unknown first argument '%s'.", mstr); } g_free(mstr); } else devc->cur_mqflags[i] &= ~(SR_MQFLAG_AC | SR_MQFLAG_DC); return JOB_CONF; }
static int recv_fetc(const struct sr_dev_inst *sdi, GMatchInfo *match) { struct dev_context *devc; struct sr_datafeed_packet packet; struct sr_datafeed_analog analog; struct sr_analog_encoding encoding; struct sr_analog_meaning meaning; struct sr_analog_spec spec; struct sr_channel *prev_chan; float fvalue; const char *s; char *mstr; int i, exp; sr_spew("FETC reply '%s'.", g_match_info_get_string(match)); devc = sdi->priv; i = devc->cur_channel->index; if (devc->cur_mq[i] == -1) /* This detects when channel P2 is reporting TEMP as an identical * copy of channel P3. In this case, we just skip P2. */ goto skip_value; s = g_match_info_get_string(match); if (!strcmp(s, "-9.90000000E+37") || !strcmp(s, "+9.90000000E+37")) { /* An invalid measurement shows up on the display as "O.L", but * comes through like this. Since comparing 38-digit floats * is rather problematic, we'll cut through this here. */ fvalue = NAN; } else { mstr = g_match_info_fetch(match, 1); if (sr_atof_ascii(mstr, &fvalue) != SR_OK) { g_free(mstr); sr_dbg("Invalid float."); return SR_ERR; } g_free(mstr); if (devc->cur_exponent[i] != 0) fvalue *= powf(10, devc->cur_exponent[i]); } if (devc->cur_unit[i] == SR_UNIT_DECIBEL_MW || devc->cur_unit[i] == SR_UNIT_DECIBEL_VOLT || devc->cur_unit[i] == SR_UNIT_PERCENTAGE) { mstr = g_match_info_fetch(match, 2); if (mstr && sr_atoi(mstr, &exp) == SR_OK) { devc->cur_digits[i] = MIN(4 - exp, devc->cur_digits[i]); devc->cur_encoding[i] = MIN(5 - exp, devc->cur_encoding[i]); } g_free(mstr); } sr_analog_init(&analog, &encoding, &meaning, &spec, devc->cur_digits[i] - devc->cur_exponent[i]); analog.meaning->mq = devc->cur_mq[i]; analog.meaning->unit = devc->cur_unit[i]; analog.meaning->mqflags = devc->cur_mqflags[i]; analog.meaning->channels = g_slist_append(NULL, devc->cur_channel); analog.num_samples = 1; analog.data = &fvalue; encoding.digits = devc->cur_encoding[i] - devc->cur_exponent[i]; packet.type = SR_DF_ANALOG; packet.payload = &analog; sr_session_send(sdi, &packet); g_slist_free(analog.meaning->channels); sr_sw_limits_update_samples_read(&devc->limits, 1); skip_value: prev_chan = devc->cur_channel; devc->cur_channel = sr_next_enabled_channel(sdi, devc->cur_channel); if (devc->cur_channel->index > prev_chan->index) return JOB_AGAIN; else return JOB_FETC; }