static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) { struct dev_context *devc; struct sr_scpi_dev_inst *scpi; struct sr_channel *ch; struct pps_channel *pch; int cmd, ret; if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; devc = sdi->priv; scpi = sdi->conn; devc->cb_data = cb_data; if ((ret = sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 10, scpi_pps_receive_data, (void *)sdi)) != SR_OK) return ret; std_session_send_df_header(sdi, LOG_PREFIX); /* Prime the pipe with the first channel's fetch. */ ch = sr_next_enabled_channel(sdi, NULL); pch = ch->priv; if ((ret = select_channel(sdi, ch)) < 0) return ret; if (pch->mq == SR_MQ_VOLTAGE) cmd = SCPI_CMD_GET_MEAS_VOLTAGE; else if (pch->mq == SR_MQ_FREQUENCY) cmd = SCPI_CMD_GET_MEAS_FREQUENCY; else if (pch->mq == SR_MQ_CURRENT) cmd = SCPI_CMD_GET_MEAS_CURRENT; else if (pch->mq == SR_MQ_POWER) cmd = SCPI_CMD_GET_MEAS_POWER; else return SR_ERR; scpi_cmd(sdi, devc->device->commands, cmd, pch->hwname); return SR_OK; }
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; }
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; }
SR_PRIV int scpi_pps_receive_data(int fd, int revents, void *cb_data) { 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; const struct sr_dev_inst *sdi; struct sr_channel *next_channel; struct sr_scpi_dev_inst *scpi; struct pps_channel *pch; const struct channel_spec *ch_spec; float f; int cmd; (void)fd; (void)revents; if (!(sdi = cb_data)) return TRUE; if (!(devc = sdi->priv)) return TRUE; scpi = sdi->conn; /* Retrieve requested value for this state. */ if (sr_scpi_get_float(scpi, NULL, &f) == SR_OK) { pch = devc->cur_channel->priv; ch_spec = &devc->device->channels[pch->hw_output_idx]; packet.type = SR_DF_ANALOG; packet.payload = &analog; /* Note: digits/spec_digits will be overridden later. */ sr_analog_init(&analog, &encoding, &meaning, &spec, 0); analog.meaning->channels = g_slist_append(NULL, devc->cur_channel); analog.num_samples = 1; analog.meaning->mq = pch->mq; if (pch->mq == SR_MQ_VOLTAGE) { analog.meaning->unit = SR_UNIT_VOLT; analog.encoding->digits = ch_spec->voltage[4]; analog.spec->spec_digits = ch_spec->voltage[3]; } else if (pch->mq == SR_MQ_CURRENT) { analog.meaning->unit = SR_UNIT_AMPERE; analog.encoding->digits = ch_spec->current[4]; analog.spec->spec_digits = ch_spec->current[3]; } else if (pch->mq == SR_MQ_POWER) { analog.meaning->unit = SR_UNIT_WATT; analog.encoding->digits = ch_spec->power[4]; analog.spec->spec_digits = ch_spec->power[3]; } analog.meaning->mqflags = SR_MQFLAG_DC; analog.data = &f; sr_session_send(sdi, &packet); g_slist_free(analog.meaning->channels); } if (g_slist_length(sdi->channels) > 1) { next_channel = sr_next_enabled_channel(sdi, devc->cur_channel); if (select_channel(sdi, next_channel) != SR_OK) { sr_err("Failed to select channel %s", next_channel->name); return FALSE; } } pch = devc->cur_channel->priv; if (pch->mq == SR_MQ_VOLTAGE) cmd = SCPI_CMD_GET_MEAS_VOLTAGE; else if (pch->mq == SR_MQ_FREQUENCY) cmd = SCPI_CMD_GET_MEAS_FREQUENCY; else if (pch->mq == SR_MQ_CURRENT) cmd = SCPI_CMD_GET_MEAS_CURRENT; else if (pch->mq == SR_MQ_POWER) cmd = SCPI_CMD_GET_MEAS_POWER; else return SR_ERR; scpi_cmd(sdi, devc->device->commands, cmd); return TRUE; }