int sr_cset(src *c, srcstmt *stmt, char *value) { int type = c->flags & ~SR_CRO; if (c->flags & SR_CRO) { sr_error(stmt->r->e, "%s is read-only", stmt->path); return -1; } switch (type) { case SR_CU32: *((uint32_t*)c->value) = sr_atoi(value); break; case SR_CU64: *((uint64_t*)c->value) = sr_atoi(value); break; case SR_CSZREF: { char *nsz = NULL; if (value) { nsz = sr_strdup(stmt->r->a, value); if (srunlikely(nsz == NULL)) { sr_error(stmt->r->e, "%s", "memory allocation failed"); return -1; } } char **sz = (char**)c->value; if (*sz) sr_free(stmt->r->a, *sz); *sz = nsz; break; } default: assert(0); } return 0; }
/** * Send a SCPI command, read the reply, parse it as comma separated list of * unsigned 8 bit integers and store the as an result in scpi_response. * * @param scpi Previously initialised SCPI device structure. * @param command The SCPI command to send to the device (can be NULL). * @param scpi_response Pointer where to store the parsed result. * * @return SR_OK upon successfully parsing all values, SR_ERR upon a parsing * error or upon no response. The allocated response must be freed by * the caller in the case of an SR_OK as well as in the case of * parsing error. */ SR_PRIV int sr_scpi_get_uint8v(struct sr_scpi_dev_inst *scpi, const char *command, GArray **scpi_response) { int tmp, ret; char *response; gchar **ptr, **tokens; GArray *response_array; ret = SR_OK; response = NULL; tokens = NULL; if (sr_scpi_get_string(scpi, command, &response) != SR_OK) if (!response) return SR_ERR; tokens = g_strsplit(response, ",", 0); ptr = tokens; response_array = g_array_sized_new(TRUE, FALSE, sizeof(uint8_t), 256); while (*ptr) { if (sr_atoi(*ptr, &tmp) == SR_OK) response_array = g_array_append_val(response_array, tmp); else ret = SR_ERR; ptr++; } g_strfreev(tokens); g_free(response); if (response_array->len == 0) { g_array_free(response_array, TRUE); *scpi_response = NULL; return SR_ERR; } *scpi_response = response_array; return ret; }
/** * This function takes a value of the form "2.000E-03", converts it to a * significand / factor pair and returns the index of an array where * a matching pair was found. * * It's a bit convoluted because of floating-point issues. The value "10.00E-09" * is parsed by g_ascii_strtod() as 0.000000009999999939, for example. * Therefore it's easier to break the number up into two strings and handle * them separately. * * @param value The string to be parsed. * @param array The array of s/f pairs. * @param array_len The number of pairs in the array. * @param result The index at which a matching pair was found. * * @return SR_ERR on any parsing error, SR_OK otherwise. */ static int array_float_get(gchar *value, const uint64_t array[][2], int array_len, int *result) { int i; uint64_t f; float s; unsigned int s_int; gchar ss[10], es[10]; memset(ss, 0, sizeof(ss)); memset(es, 0, sizeof(es)); strncpy(ss, value, 5); strncpy(es, &(value[6]), 3); if (sr_atof_ascii(ss, &s) != SR_OK) return SR_ERR; if (sr_atoi(es, &i) != SR_OK) return SR_ERR; /* Transform e.g. 10^-03 to 1000 as the array stores the inverse. */ f = pow(10, abs(i)); /* * Adjust the significand/factor pair to make sure * that f is a multiple of 1000. */ while ((int)fmod(log10(f), 3) > 0) { s *= 10; f *= 10; } /* Truncate s to circumvent rounding errors. */ s_int = (unsigned int)s; for (i = 0; i < array_len; i++) { if ( (s_int == array[i][0]) && (f == array[i][1]) ) { *result = i; return SR_OK; } } return SR_ERR; }
/** * Send a SCPI command, read the reply, parse it as an integer and store the * result in scpi_response. * * @param scpi Previously initialised SCPI device structure. * @param command The SCPI command to send to the device (can be NULL). * @param scpi_response Pointer where to store the parsed result. * * @return SR_OK on success, SR_ERR* on failure. */ SR_PRIV int sr_scpi_get_int(struct sr_scpi_dev_inst *scpi, const char *command, int *scpi_response) { int ret; char *response; response = NULL; ret = sr_scpi_get_string(scpi, command, &response); if (ret != SR_OK && !response) return ret; if (sr_atoi(response, scpi_response) == SR_OK) ret = SR_OK; else ret = SR_ERR_DATA; g_free(response); return ret; }
/** * Reads and removes the block data header from a given data input. * Format is #ndddd... with n being the number of decimal digits d. * The string dddd... contains the decimal-encoded length of the data. * Example: #9000000013 would yield a length of 13 bytes. * * @param data The input data. * @param len The determined input data length. */ static int dlm_block_data_header_process(GArray *data, int *len) { int i, n; gchar s[20]; if (g_array_index(data, gchar, 0) != '#') return SR_ERR; n = (uint8_t)(g_array_index(data, gchar, 1) - '0'); for (i = 0; i < n; i++) s[i] = g_array_index(data, gchar, 2 + i); s[i] = 0; if (sr_atoi(s, len) != SR_OK) return SR_ERR; g_array_remove_range(data, 0, 2 + n); return SR_OK; }
/** Process a complete line (without CR/LF) in buf. */ static void process_line(struct sr_dev_inst *sdi) { struct dev_context *devc; double dbl; int auxint; devc = sdi->priv; switch (devc->acq_req_pending) { case 0: /* Should not happen... */ break; case 1: /* Waiting for data reply to request */ /* Convert numbers */ switch (devc->acq_req) { case AQ_U1: case AQ_U2: case AQ_I1: case AQ_I2: if (sr_atod(devc->buf, &dbl) != SR_OK) { sr_err("Failed to convert '%s' to double, errno=%d %s", devc->buf, errno, g_strerror(errno)); dbl = 0.0; } break; case AQ_STATUS: if (sr_atoi(devc->buf, &auxint) != SR_OK) { sr_err("Failed to convert '%s' to int, errno=%d %s", devc->buf, errno, g_strerror(errno)); auxint = 0; } break; default: break; } switch (devc->acq_req) { case AQ_U1: devc->channel_status[0].output_voltage_last = dbl; break; case AQ_I1: devc->channel_status[0].output_current_last = dbl; break; case AQ_U2: devc->channel_status[1].output_voltage_last = dbl; break; case AQ_I2: devc->channel_status[1].output_current_last = dbl; break; case AQ_STATUS: /* Process status and generate data. */ if (lps_process_status(sdi, auxint) == SR_OK) { send_data(sdi); } break; default: break; } devc->acq_req_pending = 2; break; case 2: /* Waiting for OK after request */ if (strcmp(devc->buf, "OK")) { sr_err("Unexpected reply while waiting for OK: '%s'", devc->buf); } devc->acq_req_pending = 0; break; } devc->buf[0] = '\0'; devc->buflen = 0; }
SR_PRIV int gwinstek_gds_800_receive_data(int fd, int revents, void *cb_data) { struct sr_dev_inst *sdi; struct sr_scpi_dev_inst *scpi; struct dev_context *devc; struct sr_datafeed_packet packet; struct sr_datafeed_analog_old analog; char command[32]; char *response; float volts_per_division; int num_samples, i; float samples[MAX_SAMPLES]; uint32_t sample_rate; char *end_ptr; (void)fd; if (!(sdi = cb_data)) return TRUE; if (!(devc = sdi->priv)) return TRUE; scpi = sdi->conn; if (!(revents == G_IO_IN || revents == 0)) return TRUE; switch (devc->state) { case START_ACQUISITION: if (sr_scpi_send(scpi, ":TRIG:MOD 3") != SR_OK) { sr_err("Failed to set trigger mode to SINGLE."); sdi->driver->dev_acquisition_stop(sdi); return TRUE; } if (sr_scpi_send(scpi, ":STOP") != SR_OK) { sr_err("Failed to put the trigger system into STOP state."); sdi->driver->dev_acquisition_stop(sdi); return TRUE; } if (sr_scpi_send(scpi, ":RUN") != SR_OK) { sr_err("Failed to put the trigger system into RUN state."); sdi->driver->dev_acquisition_stop(sdi); return TRUE; } devc->cur_acq_channel = 0; devc->state = START_TRANSFER_OF_CHANNEL_DATA; break; case START_TRANSFER_OF_CHANNEL_DATA: if (((struct sr_channel *)g_slist_nth_data(sdi->channels, devc->cur_acq_channel))->enabled) { if (sr_scpi_send(scpi, ":ACQ%d:MEM?", devc->cur_acq_channel+1) != SR_OK) { sr_err("Failed to acquire memory."); sdi->driver->dev_acquisition_stop(sdi); return TRUE; } if (sr_scpi_read_begin(scpi) != SR_OK) { sr_err("Could not begin reading SCPI response."); sdi->driver->dev_acquisition_stop(sdi); return TRUE; } devc->state = WAIT_FOR_TRANSFER_OF_BEGIN_TRANSMISSION_COMPLETE; devc->cur_rcv_buffer_position = 0; } else { /* All channels acquired. */ if (devc->cur_acq_channel == ANALOG_CHANNELS - 1) { sr_spew("All channels acquired."); if (devc->cur_acq_frame == devc->frame_limit - 1) { /* All frames accquired. */ sr_spew("All frames acquired."); sdi->driver->dev_acquisition_stop(sdi); return TRUE; } else { /* Start acquiring next frame. */ if (devc->df_started) { packet.type = SR_DF_FRAME_END; sr_session_send(sdi, &packet); packet.type = SR_DF_FRAME_BEGIN; sr_session_send(sdi, &packet); } devc->cur_acq_frame++; devc->state = START_ACQUISITION; } } else { /* Start acquiring next channel. */ devc->cur_acq_channel++; } } break; case WAIT_FOR_TRANSFER_OF_BEGIN_TRANSMISSION_COMPLETE: if (read_data(sdi, scpi, devc, 1) == SR_OK) { if (devc->rcv_buffer[0] == '#') devc->state = WAIT_FOR_TRANSFER_OF_DATA_SIZE_DIGIT_COMPLETE; } break; case WAIT_FOR_TRANSFER_OF_DATA_SIZE_DIGIT_COMPLETE: if (read_data(sdi, scpi, devc, 1) == SR_OK) { if (devc->rcv_buffer[0] != '4' && devc->rcv_buffer[0] != '5' && devc->rcv_buffer[0] != '6') { sr_err("Data size digits is not 4, 5 or 6 but " "'%c'.", devc->rcv_buffer[0]); sdi->driver->dev_acquisition_stop(sdi); return TRUE; } else { devc->data_size_digits = devc->rcv_buffer[0] - '0'; devc->state = WAIT_FOR_TRANSFER_OF_DATA_SIZE_COMPLETE; } } break; case WAIT_FOR_TRANSFER_OF_DATA_SIZE_COMPLETE: if (read_data(sdi, scpi, devc, devc->data_size_digits) == SR_OK) { devc->rcv_buffer[devc->data_size_digits] = 0; if (sr_atoi(devc->rcv_buffer, &devc->data_size) != SR_OK) { sr_err("Could not parse data size '%s'", devc->rcv_buffer); sdi->driver->dev_acquisition_stop(sdi); return TRUE; } else devc->state = WAIT_FOR_TRANSFER_OF_SAMPLE_RATE_COMPLETE; } break; case WAIT_FOR_TRANSFER_OF_SAMPLE_RATE_COMPLETE: if (read_data(sdi, scpi, devc, sizeof(float)) == SR_OK) { /* * Contrary to the documentation, this field is * transfered with most significant byte first! */ sample_rate = RB32(devc->rcv_buffer); memcpy(&devc->sample_rate, &sample_rate, sizeof(float)); devc->state = WAIT_FOR_TRANSFER_OF_CHANNEL_INDICATOR_COMPLETE; if (!devc->df_started) { std_session_send_df_header(sdi); packet.type = SR_DF_FRAME_BEGIN; sr_session_send(sdi, &packet); devc->df_started = TRUE; } } break; case WAIT_FOR_TRANSFER_OF_CHANNEL_INDICATOR_COMPLETE: if (read_data(sdi, scpi, devc, 1) == SR_OK) devc->state = WAIT_FOR_TRANSFER_OF_RESERVED_DATA_COMPLETE; break; case WAIT_FOR_TRANSFER_OF_RESERVED_DATA_COMPLETE: if (read_data(sdi, scpi, devc, 3) == SR_OK) devc->state = WAIT_FOR_TRANSFER_OF_CHANNEL_DATA_COMPLETE; break; case WAIT_FOR_TRANSFER_OF_CHANNEL_DATA_COMPLETE: if (read_data(sdi, scpi, devc, devc->data_size - 8) == SR_OK) { /* Fetch data needed for conversion from device. */ snprintf(command, sizeof(command), ":CHAN%d:SCAL?", devc->cur_acq_channel + 1); if (sr_scpi_get_string(scpi, command, &response) != SR_OK) { sr_err("Failed to get volts per division."); sdi->driver->dev_acquisition_stop(sdi); return TRUE; } volts_per_division = g_ascii_strtod(response, &end_ptr); if (!strcmp(end_ptr, "mV")) volts_per_division *= 1.e-3; g_free(response); num_samples = (devc->data_size - 8) / 2; sr_spew("Received %d number of samples from channel " "%d.", num_samples, devc->cur_acq_channel + 1); /* Convert data. */ for (i = 0; i < num_samples; i++) samples[i] = ((float) ((int16_t) (RB16(&devc->rcv_buffer[i*2])))) / 256. * VERTICAL_DIVISIONS * volts_per_division; /* Fill frame. */ analog.channels = g_slist_append(NULL, g_slist_nth_data(sdi->channels, devc->cur_acq_channel)); analog.num_samples = num_samples; analog.data = samples; analog.mq = SR_MQ_VOLTAGE; analog.unit = SR_UNIT_VOLT; analog.mqflags = 0; packet.type = SR_DF_ANALOG_OLD; packet.payload = &analog; sr_session_send(sdi, &packet); g_slist_free(analog.channels); /* All channels acquired. */ if (devc->cur_acq_channel == ANALOG_CHANNELS - 1) { sr_spew("All channels acquired."); if (devc->cur_acq_frame == devc->frame_limit - 1) { /* All frames acquired. */ sr_spew("All frames acquired."); sdi->driver->dev_acquisition_stop(sdi); return TRUE; } else { /* Start acquiring next frame. */ if (devc->df_started) { packet.type = SR_DF_FRAME_END; sr_session_send(sdi, &packet); packet.type = SR_DF_FRAME_BEGIN; sr_session_send(sdi, &packet); } devc->cur_acq_frame++; devc->state = START_ACQUISITION; } } else { /* Start acquiring next channel. */ devc->state = START_TRANSFER_OF_CHANNEL_DATA; devc->cur_acq_channel++; return TRUE; } } break; } return TRUE; }
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; }