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_probe *probe; struct sr_serial_dev_inst *serial; GSList *devices; if (!(serial = sr_serial_dev_inst_new(conn, serialcomm))) return NULL; if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != 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. */ if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, mic_devs[idx].vendor, mic_devs[idx].device, ""))) goto scan_cleanup; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); goto scan_cleanup; } sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; sdi->driver = mic_devs[idx].di; if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "Temperature"))) goto scan_cleanup; sdi->probes = g_slist_append(sdi->probes, probe); if (mic_devs[idx].has_humidity) { if (!(probe = sr_probe_new(1, SR_PROBE_ANALOG, TRUE, "Humidity"))) goto scan_cleanup; sdi->probes = g_slist_append(sdi->probes, probe); } drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); scan_cleanup: serial_close(serial); return devices; }
static GSList *scan(GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_config *src; struct sr_probe *probe; GSList *devices, *l; const char *conn, *serialcomm; drvc = di->priv; drvc->instances = NULL; devices = 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 (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, "Colead", "SL-5868P", NULL))) return NULL; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_dbg("Device context malloc failed."); return NULL; } if (!(sdi->conn = sr_serial_dev_inst_new(conn, serialcomm))) return NULL; sdi->inst_type = SR_INST_SERIAL; sdi->priv = devc; sdi->driver = di; if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1"))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); return devices; }
static struct sr_dev_inst *dso_dev_new(int index, const struct dso_profile *prof) { struct sr_dev_inst *sdi; struct sr_probe *probe; struct drv_context *drvc; struct dev_context *devc; int i; sdi = sr_dev_inst_new(index, SR_ST_INITIALIZING, prof->vendor, prof->model, NULL); if (!sdi) return NULL; sdi->driver = di; /* * Add only the real probes -- EXT isn't a source of data, only * a trigger source internal to the device. */ for (i = 0; probe_names[i]; i++) { if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, probe_names[i]))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); } if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } devc->profile = prof; devc->dev_state = IDLE; devc->timebase = DEFAULT_TIMEBASE; devc->ch1_enabled = TRUE; devc->ch2_enabled = TRUE; devc->voltage_ch1 = DEFAULT_VOLTAGE; devc->voltage_ch2 = DEFAULT_VOLTAGE; devc->coupling_ch1 = DEFAULT_COUPLING; devc->coupling_ch2 = 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 = di->priv; drvc->instances = g_slist_append(drvc->instances, sdi); return sdi; }
static int init(struct sr_input *in, const char *filename) { struct sr_probe *probe; int 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_probe_new(i, SR_PROBE_LOGIC, TRUE, name))) return SR_ERR; in->sdi->probes = g_slist_append(in->sdi->probes, probe); } return SR_OK; }
static GSList *scan(GSList *options) { struct sr_dev_inst *sdi; struct sr_probe *probe; struct drv_context *drvc; struct dev_context *devc; GSList *devices; int i; (void)options; drvc = di->priv; devices = NULL; sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, DEMONAME, NULL, NULL); if (!sdi) { sr_err("Device instance creation failed."); return NULL; } sdi->driver = di; for (i = 0; probe_names[i]; i++) { if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_names[i]))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); } devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); if (!(devc = g_try_malloc(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } devc->sdi = sdi; devc->cur_samplerate = SR_KHZ(200); devc->limit_samples = 0; devc->limit_msec = 0; devc->sample_generator = PATTERN_SIGROK; sdi->priv = devc; return devices; }
static int init(struct sr_input *in, const char *filename) { struct sr_probe *probe; struct context *ctx; char buf[40], probename[8]; int i; if (get_wav_header(filename, buf) != SR_OK) return SR_ERR; if (!(ctx = g_try_malloc0(sizeof(struct context)))) return SR_ERR_MALLOC; /* Create a virtual device. */ in->sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, NULL, NULL, NULL); in->sdi->priv = ctx; ctx->samplerate = GUINT32_FROM_LE(*(uint32_t *)(buf + 24)); ctx->samplesize = GUINT16_FROM_LE(*(uint16_t *)(buf + 34)) / 8; if (ctx->samplesize != 1 && ctx->samplesize != 2 && ctx->samplesize != 4) { sr_err("only 8, 16 or 32 bits per sample supported."); return SR_ERR; } if ((ctx->num_channels = GUINT16_FROM_LE(*(uint16_t *)(buf + 22))) > 20) { sr_err("%d channels seems crazy.", ctx->num_channels); return SR_ERR; } for (i = 0; i < ctx->num_channels; i++) { snprintf(probename, 8, "CH%d", i + 1); if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, probename))) return SR_ERR; in->sdi->probes = g_slist_append(in->sdi->probes, probe); } return SR_OK; }
static int init(struct sr_input *in, const char *filename) { int res; struct context *ctx; const char *param; GIOStatus status; gsize i, term_pos; char probe_name[SR_MAX_PROBENAME_LEN + 1]; struct sr_probe *probe; char **columns; gsize num_columns; char *ptr; if (!(ctx = g_try_malloc0(sizeof(struct context)))) { sr_err("Context malloc failed."); return SR_ERR_MALLOC; } /* Create a virtual device. */ in->sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, NULL, NULL, NULL); in->internal = ctx; /* Set default samplerate. */ ctx->samplerate = 0; /* * Enable auto-detection of the number of probes in multi column mode * and enforce the specification of the number of probes in single * column mode. */ ctx->num_probes = 0; /* Set default delimiter. */ if (!(ctx->delimiter = g_string_new(","))) { sr_err("Delimiter malloc failed."); free_context(ctx); return SR_ERR_MALLOC; } /* * Set default comment prefix. Note that an empty comment prefix * disables removing of comments. */ if (!(ctx->comment = g_string_new(""))) { sr_err("Comment malloc failed."); free_context(ctx); return SR_ERR_MALLOC; } /* Enable multi column mode by default. */ ctx->multi_column_mode = TRUE; /* Use first column as default single column number. */ ctx->single_column = 0; /* * In multi column mode start parsing sample data at the first column * and in single column mode at the first bit. */ ctx->first_probe = 0; /* Start at the beginning of the file. */ ctx->start_line = 1; /* Disable the usage of the first line as header by default. */ ctx->header = FALSE; /* Set default format for single column mode. */ ctx->format = FORMAT_BIN; if (!(ctx->buffer = g_string_new(""))) { sr_err("Line buffer malloc failed."); free_context(ctx); return SR_ERR_MALLOC; } if (in->param) { if ((param = g_hash_table_lookup(in->param, "samplerate"))) { res = sr_parse_sizestring(param, &ctx->samplerate); if (res != SR_OK) { sr_err("Invalid samplerate: %s.", param); free_context(ctx); return SR_ERR_ARG; } } if ((param = g_hash_table_lookup(in->param, "numprobes"))) ctx->num_probes = g_ascii_strtoull(param, NULL, 10); if ((param = g_hash_table_lookup(in->param, "delimiter"))) { if (!strlen(param)) { sr_err("Delimiter must be at least one character."); free_context(ctx); return SR_ERR_ARG; } if (!g_ascii_strcasecmp(param, "\\t")) g_string_assign(ctx->delimiter, "\t"); else g_string_assign(ctx->delimiter, param); } if ((param = g_hash_table_lookup(in->param, "comment"))) g_string_assign(ctx->comment, param); if ((param = g_hash_table_lookup(in->param, "single-column"))) { ctx->single_column = g_ascii_strtoull(param, &ptr, 10); ctx->multi_column_mode = FALSE; if (param == ptr) { sr_err("Invalid single-colum number: %s.", param); free_context(ctx); return SR_ERR_ARG; } } if ((param = g_hash_table_lookup(in->param, "first-probe"))) ctx->first_probe = g_ascii_strtoull(param, NULL, 10); if ((param = g_hash_table_lookup(in->param, "startline"))) { ctx->start_line = g_ascii_strtoull(param, NULL, 10); if (ctx->start_line < 1) { sr_err("Invalid start line: %s.", param); free_context(ctx); return SR_ERR_ARG; } } if ((param = g_hash_table_lookup(in->param, "header"))) ctx->header = sr_parse_boolstring(param); if ((param = g_hash_table_lookup(in->param, "format"))) { if (!g_ascii_strncasecmp(param, "bin", 3)) { ctx->format = FORMAT_BIN; } else if (!g_ascii_strncasecmp(param, "hex", 3)) { ctx->format = FORMAT_HEX; } else if (!g_ascii_strncasecmp(param, "oct", 3)) { ctx->format = FORMAT_OCT; } else { sr_err("Invalid format: %s.", param); free_context(ctx); return SR_ERR; } } } if (ctx->multi_column_mode) ctx->first_column = ctx->first_probe; else ctx->first_column = ctx->single_column; if (!ctx->multi_column_mode && !ctx->num_probes) { sr_err("Number of probes needs to be specified in single column mode."); free_context(ctx); return SR_ERR; } if (!(ctx->channel = g_io_channel_new_file(filename, "r", NULL))) { sr_err("Input file '%s' could not be opened.", filename); free_context(ctx); return SR_ERR; } while (TRUE) { ctx->line_number++; status = g_io_channel_read_line_string(ctx->channel, ctx->buffer, &term_pos, NULL); if (status == G_IO_STATUS_EOF) { sr_err("Input file is empty."); free_context(ctx); return SR_ERR; } if (status != G_IO_STATUS_NORMAL) { sr_err("Error while reading line %zu.", ctx->line_number); free_context(ctx); return SR_ERR; } if (ctx->start_line > ctx->line_number) { sr_spew("Line %zu skipped.", ctx->line_number); continue; } /* Remove line termination character(s). */ g_string_truncate(ctx->buffer, term_pos); if (!ctx->buffer->len) { sr_spew("Blank line %zu skipped.", ctx->line_number); continue; } /* Remove trailing comment. */ strip_comment(ctx->buffer, ctx->comment); if (ctx->buffer->len) break; sr_spew("Comment-only line %zu skipped.", ctx->line_number); } /* * In order to determine the number of columns parse the current line * without limiting the number of columns. */ if (!(columns = parse_line(ctx, -1))) { sr_err("Error while parsing line %zu.", ctx->line_number); free_context(ctx); return SR_ERR; } num_columns = g_strv_length(columns); /* Ensure that the first column is not out of bounds. */ if (!num_columns) { sr_err("Column %zu in line %zu is out of bounds.", ctx->first_column, ctx->line_number); g_strfreev(columns); free_context(ctx); return SR_ERR; } if (ctx->multi_column_mode) { /* * Detect the number of probes in multi column mode * automatically if not specified. */ if (!ctx->num_probes) { ctx->num_probes = num_columns; sr_info("Number of auto-detected probes: %zu.", ctx->num_probes); } /* * Ensure that the number of probes does not exceed the number * of columns in multi column mode. */ if (num_columns < ctx->num_probes) { sr_err("Not enough columns for desired number of probes in line %zu.", ctx->line_number); g_strfreev(columns); free_context(ctx); return SR_ERR; } } for (i = 0; i < ctx->num_probes; i++) { if (ctx->header && ctx->multi_column_mode && strlen(columns[i])) snprintf(probe_name, sizeof(probe_name), "%s", columns[i]); else snprintf(probe_name, sizeof(probe_name), "%zu", i); probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name); if (!probe) { sr_err("Probe creation failed."); free_context(ctx); g_strfreev(columns); return SR_ERR; } in->sdi->probes = g_slist_append(in->sdi->probes, probe); } g_strfreev(columns); /* * Calculate the minimum buffer size to store the sample data of the * probes. */ ctx->sample_buffer_size = (ctx->num_probes + 7) >> 3; if (!(ctx->sample_buffer = g_try_malloc(ctx->sample_buffer_size))) { sr_err("Sample buffer malloc failed."); free_context(ctx); return SR_ERR_MALLOC; } return SR_OK; }
static int init(struct sr_input *in, const char *filename) { struct sr_probe *probe; int 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; ctx->downsample = 1; ctx->skip = -1; if (in->param) { param = g_hash_table_lookup(in->param, "numprobes"); if (param) { num_probes = strtoul(param, NULL, 10); if (num_probes < 1) { release_context(ctx); return SR_ERR; } } param = g_hash_table_lookup(in->param, "downsample"); if (param) { ctx->downsample = strtoul(param, NULL, 10); if (ctx->downsample < 1) { ctx->downsample = 1; } } param = g_hash_table_lookup(in->param, "compress"); if (param) { ctx->compress = strtoul(param, NULL, 10); } param = g_hash_table_lookup(in->param, "skip"); if (param) { ctx->skip = strtoul(param, NULL, 10) / ctx->downsample; } } /* Maximum number of probes to parse from the VCD */ ctx->maxprobes = num_probes; /* Create a virtual device. */ in->sdi = sr_dev_inst_new(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); if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, name))) { release_context(ctx); return SR_ERR; } in->sdi->probes = g_slist_append(in->sdi->probes, probe); } return SR_OK; }
static GSList *scan(GSList *options) { GSList *usb_devices, *devices, *l; struct drv_context *drvc; struct sr_dev_inst *sdi; struct sr_probe *probe; struct dev_context *devc; struct sr_usb_dev_inst *usb; struct device_info dev_info; int ret, device_index, i; char *fw_ver_str; (void)options; devices = NULL; drvc = di->priv; drvc->instances = NULL; device_index = 0; usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, USB_VID_PID); if (usb_devices == NULL) return NULL; for (l = usb_devices; l; l = l->next) { usb = l->data; if ((ret = sl2_get_device_info(*usb, &dev_info)) < 0) { sr_warn("Failed to get device information: %d.", ret); sr_usb_dev_inst_free(usb); continue; } if (!(devc = g_try_malloc(sizeof(struct dev_context)))) { sr_err("Device instance malloc failed."); sr_usb_dev_inst_free(usb); continue; } if (!(devc->xfer_in = libusb_alloc_transfer(0))) { sr_err("Transfer malloc failed."); sr_usb_dev_inst_free(usb); g_free(devc); continue; } if (!(devc->xfer_out = libusb_alloc_transfer(0))) { sr_err("Transfer malloc failed."); sr_usb_dev_inst_free(usb); libusb_free_transfer(devc->xfer_in); g_free(devc); continue; } fw_ver_str = g_strdup_printf("%u.%u", dev_info.fw_ver_major, dev_info.fw_ver_minor); if (!fw_ver_str) { sr_err("Firmware string malloc failed."); sr_usb_dev_inst_free(usb); libusb_free_transfer(devc->xfer_in); libusb_free_transfer(devc->xfer_out); g_free(devc); continue; } sdi = sr_dev_inst_new(device_index, SR_ST_INACTIVE, VENDOR_NAME, MODEL_NAME, fw_ver_str); g_free(fw_ver_str); if (!sdi) { sr_err("sr_dev_inst_new failed."); sr_usb_dev_inst_free(usb); libusb_free_transfer(devc->xfer_in); libusb_free_transfer(devc->xfer_out); g_free(devc); continue; } sdi->priv = devc; sdi->driver = di; sdi->inst_type = SR_INST_USB; sdi->conn = usb; for (i = 0; probe_names[i]; i++) { probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_names[i]); sdi->probes = g_slist_append(sdi->probes, probe); devc->probes[i] = probe; } devc->state = STATE_IDLE; devc->next_state = STATE_IDLE; /* Set default samplerate. */ sl2_set_samplerate(sdi, DEFAULT_SAMPLERATE); /* Set default capture ratio. */ devc->capture_ratio = 0; /* Set default after trigger delay. */ devc->after_trigger_delay = 0; memset(devc->xfer_buf_in, 0, LIBUSB_CONTROL_SETUP_SIZE + PACKET_LENGTH); memset(devc->xfer_buf_out, 0, LIBUSB_CONTROL_SETUP_SIZE + PACKET_LENGTH); libusb_fill_control_setup(devc->xfer_buf_in, USB_REQUEST_TYPE_IN, USB_HID_GET_REPORT, USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE, PACKET_LENGTH); libusb_fill_control_setup(devc->xfer_buf_out, USB_REQUEST_TYPE_OUT, USB_HID_SET_REPORT, USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE, PACKET_LENGTH); devc->xfer_data_in = devc->xfer_buf_in + LIBUSB_CONTROL_SETUP_SIZE; devc->xfer_data_out = devc->xfer_buf_out + LIBUSB_CONTROL_SETUP_SIZE; drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); device_index++; } g_slist_free(usb_devices); return devices; }
static GSList *scan(GSList *options) { struct sr_dev_inst *sdi; struct sr_probe *probe; struct drv_context *drvc; struct dev_context *devc; GSList *devices; unsigned int i; int ret; (void)options; drvc = di->priv; devices = NULL; /* Allocate memory for our private device context. */ if (!(devc = g_try_malloc(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); goto err_free_nothing; } /* Set some sane defaults. */ devc->ftdic = NULL; devc->cur_samplerate = SR_MHZ(100); /* 100MHz == max. samplerate */ devc->limit_msec = 0; devc->limit_samples = 0; devc->cb_data = NULL; memset(devc->mangled_buf, 0, BS); devc->final_buf = NULL; devc->trigger_pattern = 0x00; /* Value irrelevant, see trigger_mask. */ devc->trigger_mask = 0x00; /* All probes are "don't care". */ devc->trigger_timeout = 10; /* Default to 10s trigger timeout. */ devc->trigger_found = 0; devc->done = 0; devc->block_counter = 0; devc->divcount = 0; /* 10ns sample period == 100MHz samplerate */ devc->usb_pid = 0; /* Allocate memory where we'll store the de-mangled data. */ if (!(devc->final_buf = g_try_malloc(SDRAM_SIZE))) { sr_err("final_buf malloc failed."); goto err_free_devc; } /* Allocate memory for the FTDI context (ftdic) and initialize it. */ if (!(devc->ftdic = ftdi_new())) { sr_err("%s: ftdi_new failed.", __func__); goto err_free_final_buf; } /* Check for the device and temporarily open it. */ for (i = 0; i < ARRAY_SIZE(usb_pids); i++) { sr_dbg("Probing for VID/PID %04x:%04x.", USB_VENDOR_ID, usb_pids[i]); ret = ftdi_usb_open_desc(devc->ftdic, USB_VENDOR_ID, usb_pids[i], USB_DESCRIPTION, NULL); if (ret == 0) { sr_dbg("Found LA8 device (%04x:%04x).", USB_VENDOR_ID, usb_pids[i]); devc->usb_pid = usb_pids[i]; } } if (devc->usb_pid == 0) goto err_free_ftdic; /* Register the device with libsigrok. */ sdi = sr_dev_inst_new(0, SR_ST_INITIALIZING, USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION); if (!sdi) { sr_err("%s: sr_dev_inst_new failed.", __func__); goto err_close_ftdic; } sdi->driver = di; sdi->priv = devc; for (i = 0; chronovu_la8_probe_names[i]; i++) { if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, chronovu_la8_probe_names[i]))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); } devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); /* Close device. We'll reopen it again when we need it. */ (void) la8_close(devc); /* Log, but ignore errors. */ return devices; err_close_ftdic: (void) la8_close(devc); /* Log, but ignore errors. */ err_free_ftdic: ftdi_free(devc->ftdic); /* NOT free() or g_free()! */ err_free_final_buf: g_free(devc->final_buf); err_free_devc: g_free(devc); err_free_nothing: return NULL; }
static GSList *brymen_scan(const char *conn, const char *serialcomm) { struct sr_dev_inst *sdi; struct dev_context *devc; struct drv_context *drvc; struct sr_probe *probe; struct sr_serial_dev_inst *serial; GSList *devices; int ret; uint8_t buf[128]; size_t len; if (!(serial = sr_serial_dev_inst_new(conn, serialcomm))) return NULL; if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK) return NULL; sr_info("Probing port %s.", conn); devices = NULL; /* Request reading */ if ((ret = brymen_packet_request(serial)) < 0) { sr_err("Unable to send command: %d.", ret); goto scan_cleanup; } len = 128; ret = brymen_stream_detect(serial, buf, &len, brymen_packet_length, brymen_packet_is_valid, 1000, 9600); if (ret != SR_OK) goto scan_cleanup; sr_info("Found device on port %s.", conn); if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, "Brymen", "BM85x", ""))) goto scan_cleanup; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); goto scan_cleanup; } sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; drvc = di->priv; sdi->priv = devc; sdi->driver = di; if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1"))) goto scan_cleanup; sdi->probes = g_slist_append(sdi->probes, probe); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); scan_cleanup: serial_close(serial); return devices; }
static GSList *scan(GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_serial_dev_inst *serial; struct sr_dev_inst *sdi; struct sr_probe *probe; struct sr_config *src; GSList *devices, *l; const char *conn, *serialcomm; uint8_t buf[50]; size_t len; len = sizeof(buf); devices = 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 = "9600/8n1"; if (!(serial = sr_serial_dev_inst_new(conn, serialcomm))) return NULL; if (serial_open(serial, SERIAL_RDONLY | SERIAL_NONBLOCK) != SR_OK) return NULL; sr_info("Probing serial port %s.", conn); drvc = di->priv; drvc->instances = NULL; serial_flush(serial); /* Let's get a bit of data and see if we can find a packet. */ if (serial_stream_detect(serial, buf, &len, 25, appa_55ii_packet_valid, 500, 9600) != SR_OK) goto scan_cleanup; sr_info("Found device on port %s.", conn); if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, "APPA", "55II", ""))) goto scan_cleanup; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); goto scan_cleanup; } devc->data_source = DEFAULT_DATA_SOURCE; sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; sdi->driver = di; if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "T1"))) goto scan_cleanup; sdi->probes = g_slist_append(sdi->probes, probe); if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "T2"))) goto scan_cleanup; sdi->probes = g_slist_append(sdi->probes, probe); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); scan_cleanup: serial_close(serial); return devices; }
static GSList *scan(GSList *options, int dmm) { GSList *usb_devices, *devices, *l; struct sr_dev_inst *sdi; struct dev_context *devc; struct drv_context *drvc; struct sr_usb_dev_inst *usb; struct sr_config *src; struct sr_probe *probe; const char *conn; drvc = udmms[dmm].di->priv; 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; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } devc->first_run = TRUE; if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, udmms[dmm].vendor, udmms[dmm].device, NULL))) { sr_err("sr_dev_inst_new returned NULL."); return NULL; } sdi->priv = devc; sdi->driver = udmms[dmm].di; if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1"))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); 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 int config_set(int id, GVariant *data, struct sr_dev_inst *sdi) { int i, ret; const char *stropt; struct sr_probe *probe; struct dev_context *const devc = sdi->priv; if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; if (id == SR_CONF_SAMPLERATE) { devc->cur_samplerate = g_variant_get_uint64(data); sr_dbg("%s: setting samplerate to %" PRIu64, __func__, devc->cur_samplerate); ret = SR_OK; } else if (id == SR_CONF_LIMIT_SAMPLES) { devc->limit_msec = 0; devc->limit_samples = g_variant_get_uint64(data); sr_dbg("%s: setting limit_samples to %" PRIu64, __func__, devc->limit_samples); ret = SR_OK; } else if (id == SR_CONF_LIMIT_MSEC) { devc->limit_msec = g_variant_get_uint64(data); devc->limit_samples = 0; sr_dbg("%s: setting limit_msec to %" PRIu64, __func__, devc->limit_msec); ret = SR_OK; } else if (id == SR_CONF_DEVICE_MODE) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; if (!strcmp(stropt, mode_strings[LOGIC])) { sdi->mode = LOGIC; sr_dev_probes_free(sdi); for (i = 0; probe_names[i]; i++) { if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_names[i]))) ret = SR_ERR; else sdi->probes = g_slist_append(sdi->probes, probe); } } else if (!strcmp(stropt, mode_strings[DSO])) { sdi->mode = DSO; sr_dev_probes_free(sdi); for (i = 0; i < DS_MAX_DSO_PROBES_NUM; i++) { if (!(probe = sr_probe_new(i, SR_PROBE_DSO, TRUE, probe_names[i]))) ret = SR_ERR; else sdi->probes = g_slist_append(sdi->probes, probe); } } else if (!strcmp(stropt, mode_strings[ANALOG])) { sdi->mode = ANALOG; sr_dev_probes_free(sdi); for (i = 0; i < DS_MAX_ANALOG_PROBES_NUM; i++) { if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, probe_names[i]))) ret = SR_ERR; else sdi->probes = g_slist_append(sdi->probes, probe); } } else { ret = SR_ERR; } sr_dbg("%s: setting mode to %d", __func__, sdi->mode); }else if (id == SR_CONF_PATTERN_MODE) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; if (!strcmp(stropt, pattern_strings[PATTERN_SINE])) { devc->sample_generator = PATTERN_SINE; } else if (!strcmp(stropt, pattern_strings[PATTERN_SQUARE])) { devc->sample_generator = PATTERN_SQUARE; } else if (!strcmp(stropt, pattern_strings[PATTERN_TRIANGLE])) { devc->sample_generator = PATTERN_TRIANGLE; } else if (!strcmp(stropt, pattern_strings[PATTERN_SAWTOOTH])) { devc->sample_generator = PATTERN_SAWTOOTH; } else if (!strcmp(stropt, pattern_strings[PATTERN_RANDOM])) { devc->sample_generator = PATTERN_RANDOM; } else { ret = SR_ERR; } sr_dbg("%s: setting pattern to %d", __func__, devc->sample_generator); } else { ret = SR_ERR_NA; } return ret; }
static GSList *scan(const char *conn, const char *serialcomm, int dmm) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; struct sr_probe *probe; struct sr_serial_dev_inst *serial; GSList *devices; int dropped, ret; size_t len; uint8_t buf[128]; if (!(serial = sr_serial_dev_inst_new(conn, serialcomm))) return NULL; if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK) return NULL; sr_info("Probing serial port %s.", conn); drvc = dmms[dmm].di->priv; devices = NULL; serial_flush(serial); /* Request a packet if the DMM requires this. */ if (dmms[dmm].packet_request) { if ((ret = dmms[dmm].packet_request(serial)) < 0) { sr_err("Failed to request packet: %d.", ret); return FALSE; } } /* * There's no way to get an ID from the multimeter. It just sends data * periodically (or upon request), so the best we can do is check if * the packets match the expected format. */ /* Let's get a bit of data and see if we can find a packet. */ len = sizeof(buf); ret = serial_stream_detect(serial, buf, &len, dmms[dmm].packet_size, dmms[dmm].packet_valid, 1000, dmms[dmm].baudrate); if (ret != SR_OK) goto scan_cleanup; /* * If we dropped more than two packets worth of data, something is * wrong. We shouldn't quit however, since the dropped bytes might be * just zeroes at the beginning of the stream. Those can occur as a * combination of the nonstandard cable that ships with some devices * and the serial port or USB to serial adapter. */ dropped = len - dmms[dmm].packet_size; if (dropped > 2 * dmms[dmm].packet_size) sr_warn("Had to drop too much data."); sr_info("Found device on port %s.", conn); if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, dmms[dmm].vendor, dmms[dmm].device, ""))) goto scan_cleanup; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); goto scan_cleanup; } devc->serial = serial; sdi->priv = devc; sdi->driver = dmms[dmm].di; if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1"))) goto scan_cleanup; sdi->probes = g_slist_append(sdi->probes, probe); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); scan_cleanup: serial_close(serial); return devices; }
static GSList *hw_scan(GSList *options) { GSList *usb_devices, *devices, *l; struct sr_dev_inst *sdi; struct dev_context *devc; struct drv_context *drvc; struct sr_usb_dev_inst *usb; struct sr_config *src; struct sr_probe *probe; const char *conn; (void)options; drvc = di->priv; /* USB scan is always authoritative. */ clear_instances(); conn = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = src->value; break; } } if (!conn) conn = UNI_T_UT_D04_NEW; 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; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, di->longname, NULL, NULL))) { sr_err("sr_dev_inst_new returned NULL."); return NULL; } sdi->priv = devc; sdi->driver = di; if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1"))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); devc->usb = usb; drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); } return devices; }
static GSList *scan(GSList *options) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; struct sr_config *src; struct sr_probe *probe; struct sr_serial_dev_inst *serial; GSList *l, *devices; int len, i; const char *conn, *serialcomm; char *buf, **tokens; drvc = di->priv; drvc->instances = NULL; devices = 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); if (serial_write(serial, "*IDN?\r\n", 7) == -1) { sr_err("Unable to send identification string: %s.", strerror(errno)); return NULL; } len = 128; if (!(buf = g_try_malloc(len))) { sr_err("Serial buffer malloc failed."); return NULL; } serial_readline(serial, &buf, &len, 150); if (!len) return NULL; tokens = g_strsplit(buf, ",", 4); if (!strcmp("Agilent Technologies", tokens[0]) && tokens[1] && tokens[2] && tokens[3]) { for (i = 0; supported_agdmm[i].model; i++) { if (strcmp(supported_agdmm[i].modelname, tokens[1])) continue; if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, tokens[0], tokens[1], tokens[3]))) return NULL; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } devc->profile = &supported_agdmm[i]; devc->cur_mq = -1; sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; sdi->driver = di; if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1"))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); break; } } g_strfreev(tokens); g_free(buf); serial_close(serial); if (!devices) sr_serial_dev_inst_free(serial); return devices; }
static GSList *hw_scan(GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_usb_dev_inst *usb; struct sr_config *src; struct sr_probe *probe; libusb_device *dev; GSList *usb_devices, *devices, *l; int i; const char *conn; (void)options; drvc = di->priv; /* USB scan is always authoritative. */ clear_instances(); conn = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = src->value; break; } } if (!conn) conn = OSCI_VIDPID; devices = NULL; if ((usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn))) { for (l = usb_devices; l; l = l->next) { usb = l->data; if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, OSCI_VENDOR, OSCI_MODEL, OSCI_VERSION))) return NULL; sdi->driver = di; for (i = 0; probe_names[i]; i++) { if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, probe_names[i]))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); } if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) return NULL; sdi->priv = devc; devc->usb = usb; if (strcmp(conn, OSCI_VIDPID)) { if (sr_usb_open(drvc->sr_ctx->libusb_ctx, usb) != SR_OK) break; dev = libusb_get_device(usb->devhdl); if (ezusb_upload_firmware(dev, 0, OSCI_FIRMWARE) == SR_OK) /* Remember when the firmware on this device was updated */ devc->fw_updated = g_get_monotonic_time(); else sr_err("Firmware upload failed for device " "at bus %d address %d.", usb->bus, usb->address); } 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 int probe_port(const char *port, GSList **devices) { struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_serial_dev_inst *serial; struct sr_probe *probe; unsigned int i; int len, num_tokens; gboolean matched, has_digital; const char *manufacturer, *model, *version; char buf[256]; gchar **tokens, *channel_name; *devices = NULL; if (!(serial = sr_serial_dev_inst_new(port, NULL))) return SR_ERR_MALLOC; if (serial_open(serial, SERIAL_RDWR) != SR_OK) return SR_ERR; len = serial_write(serial, "*IDN?", 5); len = serial_read(serial, buf, sizeof(buf)); if (serial_close(serial) != SR_OK) return SR_ERR; sr_serial_dev_inst_free(serial); if (len == 0) return SR_ERR_NA; buf[len] = 0; tokens = g_strsplit(buf, ",", 0); sr_dbg("response: %s [%s]", port, buf); for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++); if (num_tokens < 4) { g_strfreev(tokens); return SR_ERR_NA; } manufacturer = tokens[0]; model = tokens[1]; version = tokens[3]; if (strcmp(manufacturer, "Rigol Technologies")) { g_strfreev(tokens); return SR_ERR_NA; } matched = has_digital = FALSE; for (i = 0; i < ARRAY_SIZE(supported_models); i++) { if (!strcmp(model, supported_models[i])) { matched = TRUE; has_digital = g_str_has_suffix(model, "D"); break; } } if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, manufacturer, model, version))) { g_strfreev(tokens); return SR_ERR_NA; } g_strfreev(tokens); if (!(sdi->conn = sr_serial_dev_inst_new(port, NULL))) return SR_ERR_MALLOC; sdi->driver = di; sdi->inst_type = SR_INST_SERIAL; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) return SR_ERR_MALLOC; devc->limit_frames = 0; devc->has_digital = has_digital; for (i = 0; i < 2; i++) { if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, i == 0 ? "CH1" : "CH2"))) return SR_ERR_MALLOC; sdi->probes = g_slist_append(sdi->probes, probe); } if (devc->has_digital) { for (i = 0; i < 16; i++) { if (!(channel_name = g_strdup_printf("D%d", i))) return SR_ERR_MALLOC; probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name); g_free(channel_name); if (!probe) return SR_ERR_MALLOC; sdi->probes = g_slist_append(sdi->probes, probe); } } sdi->priv = devc; *devices = g_slist_append(NULL, sdi); return SR_OK; }
static GSList *hw_scan(GSList *options) { int i; GSList *devices = NULL; const char *conn = NULL; const char *serialcomm = NULL; GSList *l; struct sr_config *src; struct udev *udev; (void)options; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = src->value; break; case SR_CONF_SERIALCOMM: serialcomm = src->value; break; } } if (!conn) conn = SERIALCONN; if (serialcomm == NULL) serialcomm = SERIALCOMM; udev = udev_new(); if (!udev) { sr_err("Failed to initialize udev."); } struct udev_enumerate *enumerate = udev_enumerate_new(udev); udev_enumerate_add_match_subsystem(enumerate, "usb-serial"); udev_enumerate_scan_devices(enumerate); struct udev_list_entry *devs = udev_enumerate_get_list_entry(enumerate); struct udev_list_entry *dev_list_entry; for (dev_list_entry = devs; dev_list_entry != NULL; dev_list_entry = udev_list_entry_get_next(dev_list_entry)) { const char *syspath = udev_list_entry_get_name(dev_list_entry); struct udev_device *dev = udev_device_new_from_syspath(udev, syspath); const char *sysname = udev_device_get_sysname(dev); struct udev_device *parent = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); if (!parent) { sr_err("Unable to find parent usb device for %s", sysname); continue; } const char *idVendor = udev_device_get_sysattr_value(parent, "idVendor"); const char *idProduct = udev_device_get_sysattr_value(parent, "idProduct"); if (strcmp(USB_VENDOR, idVendor) || strcmp(USB_PRODUCT, idProduct)) continue; const char *iSerial = udev_device_get_sysattr_value(parent, "serial"); const char *iProduct = udev_device_get_sysattr_value(parent, "product"); char path[32]; snprintf(path, sizeof(path), "/dev/%s", sysname); conn = path; size_t s = strcspn(iProduct, " "); char product[32]; char manufacturer[32]; if (s > sizeof(product) || strlen(iProduct) - s > sizeof(manufacturer)) { sr_err("Could not parse iProduct: %s.", iProduct); continue; } strncpy(product, iProduct, s); product[s] = 0; strcpy(manufacturer, iProduct + s + 1); //Create the device context and set its params struct dev_context *devc; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return devices; } if (mso_parse_serial(iSerial, iProduct, devc) != SR_OK) { sr_err("Invalid iSerial: %s.", iSerial); g_free(devc); return devices; } char hwrev[32]; sprintf(hwrev, "r%d", devc->hwrev); devc->ctlbase1 = 0; devc->protocol_trigger.spimode = 0; for (i = 0; i < 4; i++) { devc->protocol_trigger.word[i] = 0; devc->protocol_trigger.mask[i] = 0xff; } if (!(devc->serial = sr_serial_dev_inst_new(conn, serialcomm))) { g_free(devc); return devices; } struct sr_dev_inst *sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, manufacturer, product, hwrev); if (!sdi) { sr_err("Unable to create device instance for %s", sysname); sr_dev_inst_free(sdi); g_free(devc); return devices; } sdi->driver = di; sdi->priv = devc; for (i = 0; i < NUM_PROBES; i++) { struct sr_probe *probe; if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, mso19_probe_names[i]))) return 0; sdi->probes = g_slist_append(sdi->probes, probe); } //Add the driver struct drv_context *drvc = di->priv; drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); } return devices; }
static GSList *scan(GSList *options) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; struct sr_config *src; struct sr_probe *probe; struct sr_serial_dev_inst *serial; GSList *l, *devices; int len, cnt; const char *conn, *serialcomm; char *buf; char fmttype[10]; char req[10]; int auxtype; 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); if (!(buf = g_try_malloc(BUF_MAX))) { sr_err("Serial buffer malloc failed."); return NULL; } snprintf(req, sizeof(req), "%s\r\n", nmadmm_requests[NMADMM_REQ_IDN].req_str); for (cnt = 0; cnt < 7; cnt++) { if (serial_write(serial, req, strlen(req)) == -1) { sr_err("Unable to send identification request: %d %s.", errno, strerror(errno)); return NULL; } len = BUF_MAX; serial_readline(serial, &buf, &len, 1500); if (!len) continue; buf[BUF_MAX - 1] = '\0'; /* Match ID string, e.g. "1834 065 V1.06,IF V1.02" (DM950) */ if (g_regex_match_simple("^1834 [^,]*,IF V*", (char *)buf, 0, 0)) { auxtype = xgittoint(buf[7]); // TODO: Will this work with non-DM950? snprintf(fmttype, sizeof(fmttype), "DM9%d0", auxtype); sr_spew("Norma %s DMM %s detected!", fmttype, &buf[9]); if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, "Norma", fmttype, buf + 9))) return NULL; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } devc->type = auxtype; devc->version = g_strdup(&buf[9]); devc->elapsed_msec = g_timer_new(); sdi->conn = serial; sdi->priv = devc; sdi->driver = di; if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1"))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); break; } /* * The interface of the DM9x0 contains a cap that needs to * charge for up to 10s before the interface works, if not * powered externally. Therefore wait a little to improve * chances. */ if (cnt == 3) { sr_info("Waiting 5s to allow interface to settle."); g_usleep(5 * 1000 * 1000); } } g_free(buf); serial_close(serial); if (!devices) sr_serial_dev_inst_free(serial); return devices; }