static struct sr_dev_inst *probe_device(struct sr_modbus_dev_inst *modbus) { const struct maynuo_m97_model *model = NULL; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_channel_group *cg; struct sr_channel *ch; uint16_t id, version; unsigned int i; int ret = maynuo_m97_get_model_version(modbus, &id, &version); if (ret != SR_OK) return NULL; for (i = 0; i < ARRAY_SIZE(supported_models); i++) if (id == supported_models[i].id) { model = &supported_models[i]; break; } if (model == NULL) { sr_err("Unknown model: %d.", id); return NULL; } sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("Maynuo"); sdi->model = g_strdup(model->name); sdi->version = g_strdup_printf("v%d.%d", version/10, version%10); sdi->conn = modbus; sdi->driver = &maynuo_m97_driver_info; sdi->inst_type = SR_INST_MODBUS; cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup("1"); sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); ch = sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "V1"); cg->channels = g_slist_append(cg->channels, ch); ch = sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "I1"); cg->channels = g_slist_append(cg->channels, ch); devc = g_malloc0(sizeof(struct dev_context)); devc->model = model; sdi->priv = devc; return sdi; }
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_group *cg; if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) { sr_info("Couldn't get IDN response."); return NULL; } if (strcmp(hw_info->manufacturer, "GW") != 0 || strncmp(hw_info->model, "GDS-8", 5) != 0) { sr_scpi_hw_info_free(hw_info); return NULL; } sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->vendor = g_strdup(hw_info->manufacturer); sdi->model = g_strdup(hw_info->model); sdi->version = g_strdup(hw_info->firmware_version); sdi->conn = scpi; sdi->driver = &gwinstek_gds_800_driver_info; sdi->inst_type = SR_INST_SCPI; sdi->serial_num = g_strdup(hw_info->serial_number); sdi->channels = NULL; sdi->channel_groups = NULL; sr_scpi_hw_info_free(hw_info); devc = g_malloc0(sizeof(struct dev_context)); devc->frame_limit = 1; devc->sample_rate = 0.; devc->df_started = FALSE; sdi->priv = devc; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1"); sr_channel_new(sdi, 1, SR_CHANNEL_ANALOG, TRUE, "CH2"); cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup(""); cg->channels = g_slist_append(cg->channels, g_slist_nth_data(sdi->channels, 0)); cg->channels = g_slist_append(cg->channels, g_slist_nth_data(sdi->channels, 1)); cg->priv = NULL; sdi->channel_groups = g_slist_append(NULL, cg); return sdi; }
static GSList *center_scan(const char *conn, const char *serialcomm, int idx) { int i; struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_serial_dev_inst *serial; serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; serial_flush(serial); sr_info("Found device on port %s.", conn); sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(center_devs[idx].vendor); sdi->model = g_strdup(center_devs[idx].device); devc = g_malloc0(sizeof(struct dev_context)); sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; for (i = 0; i < center_devs[idx].num_channels; i++) sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE, channel_names[i]); serial_close(serial); return g_slist_append(NULL, sdi); }
static struct sr_dev_inst *dev_inst_new(void) { struct sr_dev_inst *sdi; struct dev_context *devc; int i; char name[8]; /* Allocate memory for our private driver context. */ devc = g_malloc0(sizeof(struct dev_context)); /* Register the device with libsigrok. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(VENDOR_NAME); sdi->model = g_strdup(MODEL_NAME); /* Enable all channels to match the default channel configuration. */ devc->channel_mask = ALL_CHANNELS_MASK; devc->samplerate = DEFAULT_SAMPLERATE; sdi->priv = devc; for (i = NUM_CHANNELS; i > 0; --i) { /* The LWLA series simply number channels from CH1 to CHxx. */ g_snprintf(name, sizeof(name), "CH%d", i); sr_channel_new(sdi, i - 1, SR_CHANNEL_LOGIC, TRUE, name); } return sdi; }
static struct sr_dev_inst *create_device(struct sr_usb_dev_inst *usb, enum sr_dev_inst_status status, int64_t fw_updated) { struct sr_dev_inst *sdi; struct dev_context *devc; char channel_name[8]; int i; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = status; sdi->vendor = g_strdup("LeCroy"); sdi->model = g_strdup("LogicStudio16"); sdi->inst_type = SR_INST_USB; sdi->conn = usb; for (i = 0; i < 16; i++) { snprintf(channel_name, sizeof(channel_name), "D%i", i); sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name); } devc = g_malloc0(sizeof(struct dev_context)); sdi->priv = devc; devc->fw_updated = fw_updated; devc->capture_ratio = 50; lls_set_samplerate(sdi, SR_MHZ(500)); return sdi; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_config *src; struct sr_serial_dev_inst *serial; struct sr_dev_inst *sdi; GSList *l, *devices; gint64 start; const char *conn; unsigned char c; conn = NULL; for (l = options; l; l = l->next) { src = l->data; if (src->key == SR_CONF_CONN) conn = g_variant_get_string(src->data, NULL); } if (!conn) return NULL; serial = sr_serial_dev_inst_new(conn, SERIALCOMM); if (serial_open(serial, SERIAL_RDONLY) != SR_OK) return NULL; devices = NULL; drvc = di->priv; start = g_get_monotonic_time(); while (g_get_monotonic_time() - start < MAX_SCAN_TIME_US) { if (serial_read_nonblocking(serial, &c, 1) == 1 && c == 0xa5) { /* Found one. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("CEM"); sdi->model = g_strdup("DT-885x"); devc = g_malloc0(sizeof(struct dev_context)); devc->cur_mqflags = 0; devc->recording = -1; devc->cur_meas_range = 0; devc->cur_data_source = DATA_SOURCE_LIVE; devc->enable_data_source_memory = FALSE; sdi->conn = sr_serial_dev_inst_new(conn, SERIALCOMM); sdi->inst_type = SR_INST_SERIAL; sdi->priv = devc; sdi->driver = di; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "SPL"); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); break; } /* It takes about 1ms for a byte to come in. */ g_usleep(1000); } serial_close(serial); return devices; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct sr_config *src; struct sr_serial_dev_inst *serial; GSList *l, *devices; const char *conn, *serialcomm; devices = NULL; drvc = di->context; drvc->instances = NULL; conn = serialcomm = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; case SR_CONF_SERIALCOMM: serialcomm = g_variant_get_string(src->data, NULL); break; } } if (!conn) return NULL; if (!serialcomm) serialcomm = SERIALCOMM; /* * We cannot scan for this device because it is write-only. * So just check that the port parameters are valid and assume that * the device is there. */ serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; serial_flush(serial); serial_close(serial); sr_spew("Conrad DIGI 35 CPU assumed at %s.", conn); sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_ACTIVE; sdi->vendor = g_strdup("Conrad"); sdi->model = g_strdup("DIGI 35 CPU"); sdi->conn = serial; sdi->priv = NULL; sdi->driver = di; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1"); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); return devices; }
static GSList *scan(GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_channel *ch; GSList *usb_devices, *devices, *l; char *model; (void)options; drvc = di->priv; drvc->instances = NULL; devices = NULL; if ((usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, USB_CONN))) { /* We have a list of sr_usb_dev_inst matching the connection * string. Wrap them in sr_dev_inst and we're done. */ for (l = usb_devices; l; l = l->next) { if (scan_kecheng(l->data, &model) != SR_OK) continue; if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, VENDOR, model, NULL))) return NULL; g_free(model); sdi->driver = di; sdi->inst_type = SR_INST_USB; sdi->conn = l->data; if (!(ch = sr_channel_new(0, SR_CHANNEL_ANALOG, TRUE, "SPL"))) return NULL; sdi->channels = g_slist_append(sdi->channels, ch); if (!(devc = g_try_malloc(sizeof(struct dev_context)))) { sr_dbg("Device context malloc failed."); return NULL; } sdi->priv = devc; devc->limit_samples = 0; /* The protocol provides no way to read the current * settings, so we'll enforce these. */ devc->sample_interval = DEFAULT_SAMPLE_INTERVAL; devc->alarm_low = DEFAULT_ALARM_LOW; devc->alarm_high = DEFAULT_ALARM_HIGH; devc->mqflags = DEFAULT_WEIGHT_TIME | DEFAULT_WEIGHT_FREQ; devc->data_source = DEFAULT_DATA_SOURCE; devc->config_dirty = FALSE; /* TODO: Set date/time? */ drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); } g_slist_free(usb_devices); } else g_slist_free_full(usb_devices, g_free); return devices; }
static GSList *mic_scan(const char *conn, const char *serialcomm, int idx) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; struct sr_serial_dev_inst *serial; GSList *devices; serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; drvc = mic_devs[idx].di->priv; devices = NULL; serial_flush(serial); /* TODO: Query device type. */ // ret = mic_cmd_get_device_info(serial); sr_info("Found device on port %s.", conn); /* TODO: Fill in version from protocol response. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(mic_devs[idx].vendor); sdi->model = g_strdup(mic_devs[idx].device); devc = g_malloc0(sizeof(struct dev_context)); sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; sdi->driver = mic_devs[idx].di; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "Temperature"); if (mic_devs[idx].has_humidity) sr_channel_new(sdi, 1, SR_CHANNEL_ANALOG, TRUE, "Humidity"); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); serial_close(serial); return devices; }
/** * Add a new channel to the specified device instance. */ SR_API int sr_dev_inst_channel_add(struct sr_dev_inst *sdi, int index, int type, const char *name) { if (!sdi || sdi->inst_type != SR_INST_USER || index < 0) return SR_ERR_ARG; sr_channel_new(sdi, index, type, TRUE, name); return SR_OK; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_config *src; GSList *l; const char *conn, *serialcomm; struct sr_serial_dev_inst *serial; conn = serialcomm = NULL; for (l = options; l; l = l->next) { if (!(src = l->data)) { sr_err("Invalid option data, skipping."); continue; } switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; case SR_CONF_SERIALCOMM: serialcomm = g_variant_get_string(src->data, NULL); break; default: sr_err("Unknown option %d, skipping.", src->key); break; } } if (!conn) return NULL; if (!serialcomm) serialcomm = SERIALCOMM; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("Tondaj"); sdi->model = g_strdup("SL-814"); devc = g_malloc0(sizeof(struct dev_context)); sr_sw_limits_init(&devc->limits); serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1"); return std_scan_complete(di, g_slist_append(NULL, sdi)); }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { GSList *usb_devices, *devices, *l; struct sr_dev_inst *sdi; struct dev_context *devc; struct drv_context *drvc; struct dmm_info *dmm; struct sr_usb_dev_inst *usb; struct sr_config *src; const char *conn; drvc = di->context; dmm = (struct dmm_info *)di; conn = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; } } if (!conn) return NULL; devices = NULL; if (!(usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn))) { g_slist_free_full(usb_devices, g_free); return NULL; } for (l = usb_devices; l; l = l->next) { usb = l->data; devc = g_malloc0(sizeof(struct dev_context)); devc->first_run = TRUE; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(dmm->vendor); sdi->model = g_strdup(dmm->device); sdi->priv = devc; sdi->driver = di; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1"); sdi->inst_type = SR_INST_USB; sdi->conn = usb; drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); } return devices; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_config *src; GSList *usb_devices, *devices, *l; unsigned int i; const char *conn; drvc = di->context; conn = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; } } if (!conn) return NULL; devices = NULL; if ((usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn))) { /* We have a list of sr_usb_dev_inst matching the connection * string. Wrap them in sr_dev_inst and we're done. */ for (l = usb_devices; l; l = l->next) { sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(VENDOR); sdi->model = g_strdup(MODEL); sdi->inst_type = SR_INST_USB; sdi->conn = l->data; for (i = 0; i < ARRAY_SIZE(channel_names); i++) sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE, channel_names[i]); devc = g_malloc0(sizeof(struct dev_context)); sdi->priv = devc; devc->limit_samples = 0; devc->data_source = DEFAULT_DATA_SOURCE; devices = g_slist_append(devices, sdi); } g_slist_free(usb_devices); } else g_slist_free_full(usb_devices, g_free); return std_scan_complete(di, devices); }
static struct sr_dev_inst *dso_dev_new(const struct dso_profile *prof) { struct sr_dev_inst *sdi; struct sr_channel *ch; struct sr_channel_group *cg; struct drv_context *drvc; struct dev_context *devc; unsigned int i; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INITIALIZING; sdi->vendor = g_strdup(prof->vendor); sdi->model = g_strdup(prof->model); sdi->driver = &hantek_dso_driver_info; /* * Add only the real channels -- EXT isn't a source of data, only * a trigger source internal to the device. */ for (i = 0; i < ARRAY_SIZE(channel_names); i++) { ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE, channel_names[i]); cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup(channel_names[i]); cg->channels = g_slist_append(cg->channels, ch); sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); } devc = g_malloc0(sizeof(struct dev_context)); devc->profile = prof; devc->dev_state = IDLE; devc->timebase = DEFAULT_TIMEBASE; devc->ch1_enabled = TRUE; devc->ch2_enabled = TRUE; devc->voltage[0] = DEFAULT_VOLTAGE; devc->voltage[1] = DEFAULT_VOLTAGE; devc->coupling[0] = DEFAULT_COUPLING; devc->coupling[1] = DEFAULT_COUPLING; devc->voffset_ch1 = DEFAULT_VERT_OFFSET; devc->voffset_ch2 = DEFAULT_VERT_OFFSET; devc->voffset_trigger = DEFAULT_VERT_TRIGGERPOS; devc->framesize = DEFAULT_FRAMESIZE; devc->triggerslope = SLOPE_POSITIVE; devc->triggersource = g_strdup(DEFAULT_TRIGGER_SOURCE); devc->triggerposition = DEFAULT_HORIZ_TRIGGERPOS; sdi->priv = devc; drvc = hantek_dso_driver_info.context; drvc->instances = g_slist_append(drvc->instances, sdi); return sdi; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; GSList *usb_devices, *devices, *l; char *model; (void)options; drvc = di->context; devices = NULL; if ((usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, USB_CONN))) { /* We have a list of sr_usb_dev_inst matching the connection * string. Wrap them in sr_dev_inst and we're done. */ for (l = usb_devices; l; l = l->next) { if (scan_kecheng(di, l->data, &model) != SR_OK) continue; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(VENDOR); sdi->model = model; /* Already g_strndup()'d. */ sdi->inst_type = SR_INST_USB; sdi->conn = l->data; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "SPL"); devc = g_malloc0(sizeof(struct dev_context)); sdi->priv = devc; devc->limit_samples = 0; /* The protocol provides no way to read the current * settings, so we'll enforce these. */ devc->sample_interval = DEFAULT_SAMPLE_INTERVAL; devc->alarm_low = DEFAULT_ALARM_LOW; devc->alarm_high = DEFAULT_ALARM_HIGH; devc->mqflags = DEFAULT_WEIGHT_TIME | DEFAULT_WEIGHT_FREQ; devc->data_source = DEFAULT_DATA_SOURCE; devc->config_dirty = FALSE; /* TODO: Set date/time? */ devices = g_slist_append(devices, sdi); } g_slist_free(usb_devices); } else g_slist_free_full(usb_devices, g_free); return std_scan_complete(di, devices); }
static int init(struct sr_input *in, const char *filename) { struct sr_channel *probe; uint16_t num_probes, i; char name[SR_MAX_PROBENAME_LEN + 1]; char *param; struct context *ctx; (void)filename; if (!(ctx = g_try_malloc0(sizeof(*ctx)))) { sr_err("Input format context malloc failed."); return SR_ERR_MALLOC; } num_probes = DEFAULT_NUM_PROBES; ctx->samplerate = 0; if (in->param) { param = g_hash_table_lookup(in->param, "numprobes"); if (param) { num_probes = strtoul(param, NULL, 10); if (num_probes < 1) return SR_ERR; } param = g_hash_table_lookup(in->param, "samplerate"); if (param) { if (sr_parse_sizestring(param, &ctx->samplerate) != SR_OK) return SR_ERR; } } /* Create a virtual device. */ in->sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_ACTIVE, NULL, NULL, NULL); in->internal = ctx; for (i = 0; i < num_probes; i++) { snprintf(name, SR_MAX_PROBENAME_LEN, "%d", i); /* TODO: Check return value. */ if (!(probe = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, name))) return SR_ERR; in->sdi->channels = g_slist_append(in->sdi->channels, probe); } return SR_OK; }
static struct sr_dev_inst *hantek_6xxx_dev_new(const struct hantek_6xxx_profile *prof) { struct sr_dev_inst *sdi; struct sr_channel *ch; struct sr_channel_group *cg; struct drv_context *drvc; struct dev_context *devc; unsigned int i; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INITIALIZING; sdi->vendor = g_strdup(prof->vendor); sdi->model = g_strdup(prof->model); sdi->driver = &hantek_6xxx_driver_info; for (i = 0; i < ARRAY_SIZE(channel_names); i++) { ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE, channel_names[i]); cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup(channel_names[i]); cg->channels = g_slist_append(cg->channels, ch); sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); } devc = g_malloc0(sizeof(struct dev_context)); for (i = 0; i < NUM_CHANNELS; i++) { devc->ch_enabled[i] = TRUE; devc->voltage[i] = DEFAULT_VOLTAGE; devc->coupling[i] = DEFAULT_COUPLING; } devc->sample_buf = NULL; devc->sample_buf_write = 0; devc->sample_buf_size = 0; devc->profile = prof; devc->dev_state = IDLE; devc->samplerate = DEFAULT_SAMPLERATE; sdi->priv = devc; drvc = sdi->driver->context; drvc->instances = g_slist_append(drvc->instances, sdi); return sdi; }
static void append_channel(struct sr_dev_inst *sdi, struct sr_channel_group *cg, int index, int type) { struct channel_priv *cp; struct dev_context *devc; struct sr_channel *ch; char *name; devc = sdi->priv; switch (type) { case ENRG_PWR: name = g_strdup_printf("P%d_ENRG_PWR", index); break; case ENRG_CURR: name = g_strdup_printf("P%d_ENRG_CURR", index); break; case ENRG_VOL: name = g_strdup_printf("P%d_ENRG_VOL", index); break; case TEMP_IN: name = g_strdup_printf("P%d_TEMP_IN", index); break; case TEMP_OUT: name = g_strdup_printf("P%d_TEMP_OUT", index); break; default: sr_err("Invalid channel type: %d.", type); return; } cp = g_malloc0(sizeof(struct channel_priv)); cp->ch_type = type; cp->probe = cg->priv; ch = sr_channel_new(sdi, devc->num_channels++, SR_CHANNEL_ANALOG, TRUE, name); g_free(name); ch->priv = cp; cg->channels = g_slist_append(cg->channels, ch); }
static int init(struct sr_input *in, GHashTable *options) { struct context *inc; int num_channels; char channelname[8]; const char *format; int fmt_index; num_channels = g_variant_get_int32(g_hash_table_lookup(options, "numchannels")); if (num_channels < 1) { sr_err("Invalid value for numchannels: must be at least 1."); return SR_ERR_ARG; } format = g_variant_get_string(g_hash_table_lookup(options, "format"), NULL); if ((fmt_index = parse_format_string(format)) == -1) { GString *formats = g_string_sized_new(200); for (unsigned int i = 0; i < ARRAY_SIZE(sample_formats); i++) g_string_append_printf(formats, "%s ", sample_formats[i].fmt_name); sr_err("Invalid format '%s': must be one of: %s.", format, formats->str); g_string_free(formats, TRUE); return SR_ERR_ARG; } in->sdi = g_malloc0(sizeof(struct sr_dev_inst)); in->priv = inc = g_malloc0(sizeof(struct context)); for (int i = 0; i < num_channels; i++) { snprintf(channelname, 8, "CH%d", i + 1); sr_channel_new(in->sdi, i, SR_CHANNEL_ANALOG, TRUE, channelname); } inc->samplerate = g_variant_get_uint64(g_hash_table_lookup(options, "samplerate")); inc->samplesize = sample_formats[fmt_index].encoding.unitsize * num_channels; init_context(inc, &sample_formats[fmt_index], in->sdi->channels); return SR_OK; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_config *src; GSList *l; const char *conn, *serialcomm; conn = serialcomm = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; case SR_CONF_SERIALCOMM: serialcomm = g_variant_get_string(src->data, NULL); break; } } if (!conn) return NULL; if (!serialcomm) serialcomm = SERIALCOMM; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("Colead"); sdi->model = g_strdup("SL-5868P"); devc = g_malloc0(sizeof(struct dev_context)); sr_sw_limits_init(&devc->limits); sdi->conn = sr_serial_dev_inst_new(conn, serialcomm); sdi->inst_type = SR_INST_SERIAL; sdi->priv = devc; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1"); return std_scan_complete(di, g_slist_append(NULL, sdi)); }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct dev_context *devc; struct sr_config *src; struct sr_serial_dev_inst *serial; struct sr_dev_inst *sdi; GSList *l; const char *conn; conn = NULL; for (l = options; l; l = l->next) { src = l->data; if (src->key == SR_CONF_CONN) conn = g_variant_get_string(src->data, NULL); } if (!conn) return NULL; serial = sr_serial_dev_inst_new(conn, SERIALCOMM); if (serial_open(serial, SERIAL_RDONLY) != SR_OK) return NULL; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("PCE"); sdi->model = g_strdup("PCE-322A"); devc = g_malloc0(sizeof(struct dev_context)); devc->cur_mqflags = SR_MQFLAG_SPL_TIME_WEIGHT_F | SR_MQFLAG_SPL_FREQ_WEIGHT_A; sdi->conn = sr_serial_dev_inst_new(conn, SERIALCOMM); sdi->inst_type = SR_INST_SERIAL; sdi->priv = devc; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "SPL"); serial_close(serial); return std_scan_complete(di, g_slist_append(NULL, sdi)); }
static int init(struct sr_input *in, GHashTable *options) { struct context *inc; int num_channels, i; char name[16]; num_channels = g_variant_get_int32(g_hash_table_lookup(options, "numchannels")); if (num_channels < 1) { sr_err("Invalid value for numchannels: must be at least 1."); return SR_ERR_ARG; } in->sdi = g_malloc0(sizeof(struct sr_dev_inst)); in->priv = inc = g_malloc0(sizeof(struct context)); inc->samplerate = g_variant_get_uint64(g_hash_table_lookup(options, "samplerate")); for (i = 0; i < num_channels; i++) { snprintf(name, 16, "%d", i); sr_channel_new(in->sdi, i, SR_CHANNEL_LOGIC, TRUE, name); } return SR_OK; }
static int process_buffer(struct sr_input *in) { struct context *inc; struct sr_datafeed_packet packet; struct sr_datafeed_meta meta; struct sr_config *src; int offset, chunk_samples, total_samples, processed, max_chunk_samples; int num_samples, i; char channelname[8]; inc = in->priv; if (!inc->started) { for (i = 0; i < inc->num_channels; i++) { snprintf(channelname, 8, "CH%d", i + 1); sr_channel_new(in->sdi, i, SR_CHANNEL_ANALOG, TRUE, channelname); } std_session_send_df_header(in->sdi, LOG_PREFIX); packet.type = SR_DF_META; packet.payload = &meta; src = sr_config_new(SR_CONF_SAMPLERATE, g_variant_new_uint64(inc->samplerate)); meta.config = g_slist_append(NULL, src); sr_session_send(in->sdi, &packet); sr_config_free(src); inc->started = TRUE; } if (!inc->found_data) { /* Skip past size of 'fmt ' chunk. */ i = 20 + RL32(in->buf->str + 16); offset = find_data_chunk(in->buf, i); if (offset < 0) { if (in->buf->len > MAX_DATA_CHUNK_OFFSET) { sr_err("Couldn't find data chunk."); return SR_ERR; } } inc->found_data = TRUE; } else offset = 0; /* Round off up to the last channels * unitsize boundary. */ chunk_samples = (in->buf->len - offset) / inc->num_channels / inc->unitsize; max_chunk_samples = CHUNK_SIZE / inc->num_channels / inc->unitsize; processed = 0; total_samples = chunk_samples; while (processed < total_samples) { if (chunk_samples > max_chunk_samples) num_samples = max_chunk_samples; else num_samples = chunk_samples; send_chunk(in, offset, num_samples); offset += num_samples * inc->unitsize; chunk_samples -= num_samples; processed += num_samples; } if ((unsigned int)offset < in->buf->len) { /* * The incoming buffer wasn't processed completely. Stash * the leftover data for next time. */ g_string_erase(in->buf, 0, offset); } else g_string_truncate(in->buf, 0); return SR_OK; }
static GSList *scan(GSList *options) { struct sr_dev_inst *sdi; struct sr_channel *ch; struct drv_context *drvc; struct dev_context *devc; const struct zp_model *prof; struct libusb_device_descriptor des; libusb_device **devlist; GSList *devices; int ret, devcnt, i, j; (void)options; drvc = di->priv; devices = NULL; /* Find all ZEROPLUS analyzers and add them to device list. */ devcnt = 0; libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); /* TODO: Errors. */ for (i = 0; devlist[i]; i++) { ret = libusb_get_device_descriptor(devlist[i], &des); if (ret != 0) { sr_err("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } prof = NULL; for (j = 0; j < zeroplus_models[j].vid; j++) { if (des.idVendor == zeroplus_models[j].vid && des.idProduct == zeroplus_models[j].pid) { prof = &zeroplus_models[j]; } } /* Skip if the device was not found. */ if (!prof) continue; sr_info("Found ZEROPLUS %s.", prof->model_name); /* Register the device with libsigrok. */ if (!(sdi = sr_dev_inst_new(devcnt, SR_ST_INACTIVE, VENDOR_NAME, prof->model_name, NULL))) { sr_err("%s: sr_dev_inst_new failed", __func__); return NULL; } sdi->driver = di; /* Allocate memory for our private driver context. */ if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } sdi->priv = devc; devc->prof = prof; devc->num_channels = prof->channels; #ifdef ZP_EXPERIMENTAL devc->max_sample_depth = 128 * 1024; devc->max_samplerate = 200; #else devc->max_sample_depth = prof->sample_depth * 1024; devc->max_samplerate = prof->max_sampling_freq; #endif devc->max_samplerate *= SR_MHZ(1); devc->memory_size = MEMORY_SIZE_8K; // memset(devc->trigger_buffer, 0, NUM_TRIGGER_STAGES); /* Fill in channellist according to this device's profile. */ for (j = 0; j < devc->num_channels; j++) { if (!(ch = sr_channel_new(j, SR_CHANNEL_LOGIC, TRUE, channel_names[j]))) return NULL; sdi->channels = g_slist_append(sdi->channels, ch); } devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); devcnt++; } libusb_free_device_list(devlist, 1); return devices; }
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_group *cg; struct sr_channel *ch; const struct scpi_pps *device; struct pps_channel *pch; struct channel_spec *channels; struct channel_group_spec *channel_groups, *cgs; struct pps_channel_group *pcg; GRegex *model_re; GMatchInfo *model_mi; GSList *l; uint64_t mask; unsigned int num_channels, num_channel_groups, ch_num, ch_idx, i, j; int ret; const char *vendor; char ch_name[16]; if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) { sr_info("Couldn't get IDN response."); return NULL; } device = NULL; for (i = 0; i < num_pps_profiles; i++) { vendor = sr_vendor_alias(hw_info->manufacturer); if (g_ascii_strcasecmp(vendor, pps_profiles[i].vendor)) continue; model_re = g_regex_new(pps_profiles[i].model, 0, 0, NULL); if (g_regex_match(model_re, hw_info->model, 0, &model_mi)) device = &pps_profiles[i]; g_match_info_unref(model_mi); g_regex_unref(model_re); if (device) break; } if (!device) { sr_scpi_hw_info_free(hw_info); return NULL; } sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(vendor); sdi->model = g_strdup(hw_info->model); sdi->version = g_strdup(hw_info->firmware_version); sdi->conn = scpi; sdi->driver = &scpi_pps_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->device = device; sdi->priv = devc; if (device->num_channels) { /* Static channels and groups. */ channels = (struct channel_spec *)device->channels; num_channels = device->num_channels; channel_groups = (struct channel_group_spec *)device->channel_groups; num_channel_groups = device->num_channel_groups; } else { /* Channels and groups need to be probed. */ ret = device->probe_channels(sdi, hw_info, &channels, &num_channels, &channel_groups, &num_channel_groups); if (ret != SR_OK) { sr_err("Failed to probe for channels."); return NULL; } /* * Since these were dynamically allocated, we'll need to free them * later. */ devc->channels = channels; devc->channel_groups = channel_groups; } ch_idx = 0; for (ch_num = 0; ch_num < num_channels; ch_num++) { /* Create one channel per measurable output unit. */ for (i = 0; i < ARRAY_SIZE(pci); i++) { if (!scpi_cmd_get(devc->device->commands, pci[i].command)) continue; g_snprintf(ch_name, 16, "%s%s", pci[i].prefix, channels[ch_num].name); ch = sr_channel_new(sdi, ch_idx++, SR_CHANNEL_ANALOG, TRUE, ch_name); pch = g_malloc0(sizeof(struct pps_channel)); pch->hw_output_idx = ch_num; pch->hwname = channels[ch_num].name; pch->mq = pci[i].mq; ch->priv = pch; } } for (i = 0; i < num_channel_groups; i++) { cgs = &channel_groups[i]; cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup(cgs->name); for (j = 0, mask = 1; j < 64; j++, mask <<= 1) { if (cgs->channel_index_mask & mask) { for (l = sdi->channels; l; l = l->next) { ch = l->data; pch = ch->priv; if (pch->hw_output_idx == j) cg->channels = g_slist_append(cg->channels, ch); } } } pcg = g_malloc0(sizeof(struct pps_channel_group)); pcg->features = cgs->features; cg->priv = pcg; sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); } sr_scpi_hw_info_free(hw_info); hw_info = NULL; scpi_cmd(sdi, devc->device->commands, SCPI_CMD_LOCAL); sr_scpi_close(scpi); return sdi; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_config *src; struct sr_serial_dev_inst *serial; struct sr_channel_group *cg; struct sr_channel *ch; GSList *l; int ret, len; const char *conn, *serialcomm; char buf[100]; char *bufptr; double version; conn = serialcomm = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; case SR_CONF_SERIALCOMM: serialcomm = g_variant_get_string(src->data, NULL); break; } } if (!conn) return NULL; if (!serialcomm) serialcomm = SERIALCOMM; serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; serial_flush(serial); if (serial_write_blocking(serial, CMD_VERSION, strlen(CMD_VERSION), serial_timeout(serial, strlen(CMD_VERSION))) < (int)strlen(CMD_VERSION)) { sr_dbg("Unable to write while probing for hardware."); serial_close(serial); return NULL; } memset(buf, 0, sizeof(buf)); bufptr = buf; len = sizeof(buf); ret = serial_readline(serial, &bufptr, &len, 3000); if (ret < 0 || len < 9 || strncmp((const char *)&buf, "version ", 8)) { sr_dbg("Unable to probe version number."); serial_close(serial); return NULL; } version = g_ascii_strtod(buf + 8, NULL); if (version < 1.10) { sr_info("Firmware >= 1.10 required (got %1.2f).", version); serial_close(serial); return NULL; } sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("Arachnid Labs"); sdi->model = g_strdup("Re:load Pro"); sdi->version = g_strdup(buf + 8); sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup("1"); sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); ch = sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "V"); cg->channels = g_slist_append(cg->channels, ch); ch = sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "I"); cg->channels = g_slist_append(cg->channels, ch); devc = g_malloc0(sizeof(struct dev_context)); sr_sw_limits_init(&devc->limits); sdi->priv = devc; serial_close(serial); return std_scan_complete(di, g_slist_append(NULL, sdi)); }
SR_PRIV int hmo_init_device(struct sr_dev_inst *sdi) { char tmp[25]; int model_index; unsigned int i, j; struct sr_channel *ch; struct dev_context *devc; devc = sdi->priv; model_index = -1; /* Find the exact model. */ for (i = 0; i < ARRAY_SIZE(scope_models); i++) { for (j = 0; scope_models[i].name[j]; j++) { if (!strcmp(sdi->model, scope_models[i].name[j])) { model_index = i; break; } } if (model_index != -1) break; } if (model_index == -1) { sr_dbg("Unsupported HMO device."); return SR_ERR_NA; } devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) * scope_models[model_index].analog_channels); devc->digital_groups = g_malloc0(sizeof(struct sr_channel_group*) * scope_models[model_index].digital_pods); /* Add analog channels. */ for (i = 0; i < scope_models[model_index].analog_channels; i++) { ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE, (*scope_models[model_index].analog_names)[i]); devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group)); devc->analog_groups[i]->name = g_strdup( (char *)(*scope_models[model_index].analog_names)[i]); devc->analog_groups[i]->channels = g_slist_append(NULL, ch); sdi->channel_groups = g_slist_append(sdi->channel_groups, devc->analog_groups[i]); } /* Add digital channel groups. */ for (i = 0; i < scope_models[model_index].digital_pods; ++i) { g_snprintf(tmp, 25, "POD%d", i); devc->digital_groups[i] = g_malloc0(sizeof(struct sr_channel_group)); devc->digital_groups[i]->name = g_strdup(tmp); sdi->channel_groups = g_slist_append(sdi->channel_groups, devc->digital_groups[i < 8 ? 0 : 1]); } /* Add digital channels. */ for (i = 0; i < scope_models[model_index].digital_channels; i++) { ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, (*scope_models[model_index].digital_names)[i]); devc->digital_groups[i < 8 ? 0 : 1]->channels = g_slist_append( devc->digital_groups[i < 8 ? 0 : 1]->channels, ch); } devc->model_config = &scope_models[model_index]; devc->frame_limit = 0; if (!(devc->model_state = scope_state_new(devc->model_config))) return SR_ERR_MALLOC; return SR_OK; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; const struct zp_model *prof; struct libusb_device_descriptor des; struct libusb_device_handle *hdl; libusb_device **devlist; GSList *devices; int ret, i, j; char serial_num[64], connection_id[64]; (void)options; drvc = di->priv; devices = NULL; /* Find all ZEROPLUS analyzers and add them to device list. */ libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); /* TODO: Errors. */ for (i = 0; devlist[i]; i++) { ret = libusb_get_device_descriptor(devlist[i], &des); if (ret != 0) { sr_err("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } if ((ret = libusb_open(devlist[i], &hdl)) < 0) continue; if (des.iSerialNumber == 0) { serial_num[0] = '\0'; } else if ((ret = libusb_get_string_descriptor_ascii(hdl, des.iSerialNumber, (unsigned char *) serial_num, sizeof(serial_num))) < 0) { sr_warn("Failed to get serial number string descriptor: %s.", libusb_error_name(ret)); continue; } libusb_close(hdl); usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)); prof = NULL; for (j = 0; j < zeroplus_models[j].vid; j++) { if (des.idVendor == zeroplus_models[j].vid && des.idProduct == zeroplus_models[j].pid) { prof = &zeroplus_models[j]; } } /* Skip if the device was not found. */ if (!prof) continue; sr_info("Found ZEROPLUS %s.", prof->model_name); /* Register the device with libsigrok. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(VENDOR_NAME); sdi->model = g_strdup(prof->model_name); sdi->driver = di; sdi->serial_num = g_strdup(serial_num); sdi->connection_id = g_strdup(connection_id); /* Allocate memory for our private driver context. */ devc = g_malloc0(sizeof(struct dev_context)); sdi->priv = devc; devc->prof = prof; devc->num_channels = prof->channels; #ifdef ZP_EXPERIMENTAL devc->max_sample_depth = 128 * 1024; devc->max_samplerate = 200; #else devc->max_sample_depth = prof->sample_depth * 1024; devc->max_samplerate = prof->max_sampling_freq; #endif devc->max_samplerate *= SR_MHZ(1); devc->memory_size = MEMORY_SIZE_8K; // memset(devc->trigger_buffer, 0, NUM_TRIGGER_STAGES); /* Fill in channellist according to this device's profile. */ for (j = 0; j < devc->num_channels; j++) sr_channel_new(sdi, j, SR_CHANNEL_LOGIC, TRUE, channel_names[j]); devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); } libusb_free_device_list(devlist, 1); return devices; }
static GSList *scan(GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_channel *ch; struct sr_channel_group *cg; struct sr_config *src; struct analog_gen *ag; GSList *devices, *l; int num_logic_channels, num_analog_channels, pattern, i; char channel_name[16]; drvc = di->priv; num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS; num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_NUM_LOGIC_CHANNELS: num_logic_channels = g_variant_get_int32(src->data); break; case SR_CONF_NUM_ANALOG_CHANNELS: num_analog_channels = g_variant_get_int32(src->data); break; } } devices = NULL; sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL); if (!sdi) { sr_err("Device instance creation failed."); return NULL; } sdi->driver = di; if (!(devc = g_try_malloc(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } devc->cur_samplerate = SR_KHZ(200); devc->limit_samples = 0; devc->limit_msec = 0; devc->step = 0; devc->num_logic_channels = num_logic_channels; devc->logic_unitsize = (devc->num_logic_channels + 7) / 8; devc->logic_pattern = PATTERN_SIGROK; devc->num_analog_channels = num_analog_channels; devc->analog_channel_groups = NULL; /* Logic channels, all in one channel group. */ if (!(cg = g_try_malloc(sizeof(struct sr_channel_group)))) return NULL; cg->name = g_strdup("Logic"); cg->channels = NULL; cg->priv = NULL; for (i = 0; i < num_logic_channels; i++) { sprintf(channel_name, "D%d", i); if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, channel_name))) return NULL; sdi->channels = g_slist_append(sdi->channels, ch); cg->channels = g_slist_append(cg->channels, ch); } sdi->channel_groups = g_slist_append(NULL, cg); /* Analog channels, channel groups and pattern generators. */ pattern = 0; for (i = 0; i < num_analog_channels; i++) { sprintf(channel_name, "A%d", i); if (!(ch = sr_channel_new(i + num_logic_channels, SR_CHANNEL_ANALOG, TRUE, channel_name))) return NULL; sdi->channels = g_slist_append(sdi->channels, ch); /* Every analog channel gets its own channel group. */ if (!(cg = g_try_malloc(sizeof(struct sr_channel_group)))) return NULL; cg->name = g_strdup(channel_name); cg->channels = g_slist_append(NULL, ch); /* Every channel group gets a generator struct. */ if (!(ag = g_try_malloc(sizeof(struct analog_gen)))) return NULL; ag->packet.channels = cg->channels; ag->packet.mq = 0; ag->packet.mqflags = 0; ag->packet.unit = SR_UNIT_VOLT; ag->packet.data = ag->pattern_data; ag->pattern = pattern; cg->priv = ag; sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); devc->analog_channel_groups = g_slist_append(devc->analog_channel_groups, cg); if (++pattern == ARRAY_SIZE(analog_pattern_str)) pattern = 0; } sdi->priv = devc; devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); return devices; }
static GSList *scan(GSList *options, int modelid) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; struct sr_config *src; struct sr_channel *ch; struct sr_channel_group *cg; struct sr_serial_dev_inst *serial; GSList *l, *devices; struct pps_model *model; uint8_t packet[PACKET_SIZE]; unsigned int i; int ret; const char *conn, *serialcomm; char channel[10]; devices = NULL; drvc = di->priv; drvc->instances = NULL; conn = serialcomm = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; case SR_CONF_SERIALCOMM: serialcomm = g_variant_get_string(src->data, NULL); break; } } if (!conn) return NULL; if (!serialcomm) serialcomm = SERIALCOMM; if (!(serial = sr_serial_dev_inst_new(conn, serialcomm))) return NULL; if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK) return NULL; serial_flush(serial); /* This is how the vendor software channels for hardware. */ memset(packet, 0, PACKET_SIZE); packet[0] = 0xaa; packet[1] = 0xaa; if (serial_write(serial, packet, PACKET_SIZE) == -1) { sr_err("Unable to write while probing for hardware: %s", strerror(errno)); return NULL; } /* The device responds with a 24-byte packet when it receives a packet. * At 9600 baud, 300ms is long enough for it to have arrived. */ g_usleep(300 * 1000); memset(packet, 0, PACKET_SIZE); if ((ret = serial_read_nonblocking(serial, packet, PACKET_SIZE)) < 0) { sr_err("Unable to read while probing for hardware: %s", strerror(errno)); return NULL; } if (ret != PACKET_SIZE || packet[0] != 0xaa || packet[1] != 0xaa) { /* Doesn't look like an Atten PPS. */ return NULL; } model = NULL; for (i = 0; i < ARRAY_SIZE(models); i++) { if (models[i].modelid == modelid) { model = &models[i]; break; } } if (!model) { sr_err("Unknown modelid %d", modelid); return NULL; } sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, "Atten", model->name, NULL); sdi->driver = di; sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; for (i = 0; i < MAX_CHANNELS; i++) { snprintf(channel, 10, "CH%d", i + 1); ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE, channel); sdi->channels = g_slist_append(sdi->channels, ch); cg = g_malloc(sizeof(struct sr_channel_group)); cg->name = g_strdup(channel); cg->channels = g_slist_append(NULL, ch); cg->priv = NULL; sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); } devc = g_malloc0(sizeof(struct dev_context)); devc->model = model; devc->config = g_malloc0(sizeof(struct per_channel_config) * model->num_channels); sdi->priv = devc; drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); serial_close(serial); if (!devices) sr_serial_dev_inst_free(serial); return devices; }