/** * @private * * Convert a string representation of a numeric value (base 10) to an integer. The * conversion is strict and will fail if the complete string does not represent * a valid integer. The function sets errno according to the details of the * failure. * * @param str The string representation to convert. * @param ret Pointer to int where the result of the conversion will be stored. * * @retval SR_OK Conversion successful. * @retval SR_ERR Failure. * * @since 0.3.0 */ SR_PRIV int sr_atoi(const char *str, int *ret) { long tmp; if (sr_atol(str, &tmp) != SR_OK) return SR_ERR; if ((int) tmp != tmp) { errno = ERANGE; return SR_ERR; } *ret = (int) tmp; return SR_OK; }
static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi) { struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_scpi_hw_info *hw_info; struct sr_channel *ch; long n[3]; unsigned int i; const struct rigol_ds_model *model = NULL; gchar *channel_name, **version; if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) { sr_info("Couldn't get IDN response, retrying."); sr_scpi_close(scpi); sr_scpi_open(scpi); if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) { sr_info("Couldn't get IDN response."); return NULL; } } for (i = 0; i < ARRAY_SIZE(supported_models); i++) { if (!g_ascii_strcasecmp(hw_info->manufacturer, supported_models[i].series->vendor->full_name) && !strcmp(hw_info->model, supported_models[i].name)) { model = &supported_models[i]; break; } } if (!model) { sr_scpi_hw_info_free(hw_info); return NULL; } sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->vendor = g_strdup(model->series->vendor->name); sdi->model = g_strdup(model->name); sdi->version = g_strdup(hw_info->firmware_version); sdi->conn = scpi; sdi->driver = &rigol_ds_driver_info; sdi->inst_type = SR_INST_SCPI; sdi->serial_num = g_strdup(hw_info->serial_number); devc = g_malloc0(sizeof(struct dev_context)); devc->limit_frames = 0; devc->model = model; devc->format = model->series->format; /* DS1000 models with firmware before 0.2.4 used the old data format. */ if (model->series == SERIES(DS1000)) { version = g_strsplit(hw_info->firmware_version, ".", 0); do { if (!version[0] || !version[1] || !version[2]) break; if (version[0][0] == 0 || version[1][0] == 0 || version[2][0] == 0) break; for (i = 0; i < 3; i++) { if (sr_atol(version[i], &n[i]) != SR_OK) break; } if (i != 3) break; scpi->firmware_version = n[0] * 100 + n[1] * 10 + n[2]; if (scpi->firmware_version < 24) { sr_dbg("Found DS1000 firmware < 0.2.4, using raw data format."); devc->format = FORMAT_RAW; } break; } while (0); g_strfreev(version); } sr_scpi_hw_info_free(hw_info); devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) * model->analog_channels); for (i = 0; i < model->analog_channels; i++) { channel_name = g_strdup_printf("CH%d", i + 1); ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE, channel_name); devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group)); devc->analog_groups[i]->name = channel_name; devc->analog_groups[i]->channels = g_slist_append(NULL, ch); sdi->channel_groups = g_slist_append(sdi->channel_groups, devc->analog_groups[i]); } if (devc->model->has_digital) { devc->digital_group = g_malloc0(sizeof(struct sr_channel_group)); for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) { channel_name = g_strdup_printf("D%d", i); ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name); g_free(channel_name); devc->digital_group->channels = g_slist_append( devc->digital_group->channels, ch); } devc->digital_group->name = g_strdup("LA"); sdi->channel_groups = g_slist_append(sdi->channel_groups, devc->digital_group); } for (i = 0; i < NUM_TIMEBASE; i++) { if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2]))) devc->timebases = &timebases[i]; if (!memcmp(&devc->model->series->max_timebase, &timebases[i], sizeof(uint64_t[2]))) devc->num_timebases = &timebases[i] - devc->timebases + 1; } for (i = 0; i < NUM_VDIV; i++) { if (!memcmp(&devc->model->series->min_vdiv, &vdivs[i], sizeof(uint64_t[2]))) { devc->vdivs = &vdivs[i]; devc->num_vdivs = NUM_VDIV - i; } } devc->buffer = g_malloc(ACQ_BUFFER_SIZE); devc->data = g_malloc(ACQ_BUFFER_SIZE * sizeof(float)); devc->data_source = DATA_SOURCE_LIVE; sdi->priv = devc; return sdi; }