static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_config *src; struct sr_serial_dev_inst *serial; 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; /* * 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_INACTIVE; sdi->vendor = g_strdup("Conrad"); sdi->model = g_strdup("DIGI 35 CPU"); devc = g_malloc0(sizeof(struct dev_context)); sr_sw_limits_init(&devc->limits); sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1"); 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_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) { 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 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)); }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { int i, model_id; struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_config *src; GSList *devices, *l; const char *conn, *serialcomm; struct sr_serial_dev_inst *serial; char reply[50], **tokens, *dummy; drvc = di->context; drvc->instances = NULL; devices = NULL; conn = NULL; serialcomm = NULL; devc = 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; default: sr_err("Unknown option %d, skipping.", src->key); break; } } if (!conn) return NULL; if (!serialcomm) serialcomm = "9600/8n1"; serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; serial_flush(serial); sr_info("Probing serial port %s.", conn); /* Get the device model. */ memset(&reply, 0, sizeof(reply)); if ((hcs_send_cmd(serial, "GMOD\r") < 0) || (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0)) return NULL; tokens = g_strsplit((const gchar *)&reply, "\r", 2); model_id = -1; for (i = 0; models[i].id != NULL; i++) { if (!strcmp(models[i].id, tokens[0])) model_id = i; } if (model_id < 0) { sr_err("Unknown model ID '%s' detected, aborting.", tokens[0]); g_strfreev(tokens); return NULL; } g_strfreev(tokens); /* Init device instance, etc. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("Manson"); sdi->model = g_strdup(models[model_id].name); sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->driver = di; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1"); devc = g_malloc0(sizeof(struct dev_context)); sr_sw_limits_init(&devc->limits); devc->model = &models[model_id]; sdi->priv = devc; /* Get current voltage, current, status. */ if ((hcs_send_cmd(serial, "GETD\r") < 0) || (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0)) goto exit_err; tokens = g_strsplit((const gchar *)&reply, "\r", 2); if (hcs_parse_volt_curr_mode(sdi, tokens) < 0) { g_strfreev(tokens); goto exit_err; } g_strfreev(tokens); /* Get max. voltage and current. */ if ((hcs_send_cmd(serial, "GMAX\r") < 0) || (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0)) goto exit_err; tokens = g_strsplit((const gchar *)&reply, "\r", 2); devc->current_max_device = g_strtod(&tokens[0][3], &dummy) * devc->model->current[2]; tokens[0][3] = '\0'; devc->voltage_max_device = g_strtod(tokens[0], &dummy) * devc->model->voltage[2]; g_strfreev(tokens); 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; exit_err: sr_dev_inst_free(sdi); g_free(devc); return NULL; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct scale_info *scale; struct sr_config *src; GSList *l, *devices; const char *conn, *serialcomm; struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_serial_dev_inst *serial; int ret; size_t len; uint8_t buf[128]; scale = (struct scale_info *)di; 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 = scale->conn; serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; sr_info("Probing serial port %s.", conn); devices = NULL; serial_flush(serial); sr_spew("Set O1 mode (continuous values, stable and unstable ones)."); if (serial_write_nonblocking(serial, "O1\r\n", 4) != 4) goto scan_cleanup; /* Device replies with "A00\r\n" (OK) or "E01\r\n" (Error). Ignore. */ /* 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, scale->packet_size, scale->packet_valid, 3000, scale->baudrate); if (ret != SR_OK) goto scan_cleanup; 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(scale->vendor); sdi->model = g_strdup(scale->device); devc = g_malloc0(sizeof(struct dev_context)); sr_sw_limits_init(&devc->limits); sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "Mass"); devices = g_slist_append(devices, sdi); scan_cleanup: serial_close(serial); return std_scan_complete(di, devices); }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct dev_context *devc; GSList *l; struct sr_dev_inst *sdi; struct sr_config *src; const char *conn, *serialcomm; struct sr_serial_dev_inst *serial; char reply[50]; int i, model_id; unsigned int len; conn = NULL; 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; default: sr_err("Unknown option %d, skipping.", src->key); break; } } if (!conn) return NULL; if (!serialcomm) serialcomm = "9600/8n1"; serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; serial_flush(serial); /* Get the device model. */ len = 0; for (i = 0; models[i].id; i++) { if (strlen(models[i].id) > len) len = strlen(models[i].id); } memset(&reply, 0, sizeof(reply)); sr_dbg("Want max %d bytes.", len); if ((korad_kaxxxxp_send_cmd(serial, "*IDN?") < 0)) return NULL; /* i is used here for debug purposes only. */ if ((i = korad_kaxxxxp_read_chars(serial, len, reply)) < 0) return NULL; sr_dbg("Received: %d, %s", i, reply); model_id = -1; for (i = 0; models[i].id; i++) { if (!strcmp(models[i].id, reply)) model_id = i; } if (model_id < 0) { sr_err("Unknown model ID '%s' detected, aborting.", reply); return NULL; } sr_dbg("Found: %s %s (idx %d, ID '%s').", models[model_id].vendor, models[model_id].name, model_id, models[model_id].id); /* Init device instance, etc. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(models[model_id].vendor); sdi->model = g_strdup(models[model_id].name); sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1"); devc = g_malloc0(sizeof(struct dev_context)); sr_sw_limits_init(&devc->limits); devc->model = &models[model_id]; devc->reply[5] = 0; devc->req_sent_at = 0; sdi->priv = devc; /* Get current status of device. */ if (korad_kaxxxxp_get_all_values(serial, devc) < 0) goto exit_err; serial_close(serial); return std_scan_complete(di, g_slist_append(NULL, sdi)); exit_err: sr_dev_inst_free(sdi); g_free(devc); sr_dbg("Scan failed."); return NULL; }
/** * Scan for Metrahit 2x in a bidirectional mode using Gossen Metrawatt * 'BD 232' interface. */ static GSList *scan_2x_bd232(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; GSList *l, *devices; const char *conn, *serialcomm; int cnt, byte; gint64 timeout_us; sdi = NULL; devc = NULL; conn = serialcomm = NULL; devices = NULL; sr_spew("scan_2x_bd232() called!"); 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_2X; serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) goto exit_err; devc = g_malloc0(sizeof(struct dev_context)); sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(VENDOR_GMC); sdi->priv = devc; /* Send message 03 "Query multimeter version and status" */ sdi->conn = serial; if (req_stat14(sdi, TRUE) != SR_OK) goto exit_err; /* Wait for reply from device(s) for up to 2s. */ timeout_us = g_get_monotonic_time() + (2 * 1000 * 1000); while (timeout_us > g_get_monotonic_time()) { /* Receive reply (14 bytes) */ devc->buflen = 0; for (cnt = 0; cnt < GMC_REPLY_SIZE; cnt++) { byte = read_byte(serial, timeout_us); if (byte != -1) devc->buf[devc->buflen++] = (byte & MASK_6BITS); } if (devc->buflen != GMC_REPLY_SIZE) continue; devc->addr = devc->buf[0]; process_msg14(sdi); devc->buflen = 0; if (devc->model != METRAHIT_NONE) { sr_spew("%s %s detected!", VENDOR_GMC, gmc_model_str(devc->model)); sr_sw_limits_init(&devc->limits); sdi->model = g_strdup(gmc_model_str(devc->model)); sdi->version = g_strdup_printf("Firmware %d.%d", devc->fw_ver_maj, devc->fw_ver_min); sdi->conn = serial; sdi->priv = devc; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1"); devices = g_slist_append(devices, sdi); devc = g_malloc0(sizeof(struct dev_context)); sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(VENDOR_GMC); } }; /* Free last alloc if no device found */ if (devc->model == METRAHIT_NONE) { g_free(devc); sr_dev_inst_free(sdi); } return std_scan_complete(di, devices); exit_err: sr_info("scan_2x_bd232(): Error!"); sr_serial_dev_inst_free(serial); g_free(devc); sr_dev_inst_free(sdi); return NULL; }
/** * Scan for Metrahit 1x and Metrahit 2x in send mode using Gossen Metrawatt * 'RS232' interface. * * The older 1x models use 8192 baud and the newer 2x 9600 baud. * The DMM usually sends up to about 20 messages per second. However, depending * on configuration and measurement mode the intervals can be much larger and * then the detection might not work. */ static GSList *scan_1x_2x_rs232(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; GSList *l, *devices; const char *conn, *serialcomm; enum model model; gboolean serialcomm_given; devices = NULL; conn = serialcomm = NULL; serialcomm_given = FALSE; sr_spew("scan_1x_2x_rs232() called!"); 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); serialcomm_given = TRUE; break; } } if (!conn) return NULL; if (!serialcomm) serialcomm = SERIALCOMM_2X_RS232; serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) { sr_serial_dev_inst_free(serial); return NULL; } serial_flush(serial); model = scan_model_sm(serial); /* * If detection failed and no user-supplied parameters, * try second baud rate. */ if ((model == METRAHIT_NONE) && !serialcomm_given) { serialcomm = SERIALCOMM_1X_RS232; g_free(serial->serialcomm); serial->serialcomm = g_strdup(serialcomm); if (serial_set_paramstr(serial, serialcomm) == SR_OK) { serial_flush(serial); model = scan_model_sm(serial); } } if (model != METRAHIT_NONE) { sr_spew("%s %s detected!", VENDOR_GMC, gmc_model_str(model)); sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(VENDOR_GMC); sdi->model = g_strdup(gmc_model_str(model)); devc = g_malloc0(sizeof(struct dev_context)); sr_sw_limits_init(&devc->limits); devc->model = model; devc->settings_ok = FALSE; sdi->conn = serial; sdi->priv = devc; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1"); devices = g_slist_append(devices, sdi); } return std_scan_complete(di, devices); }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct dmm_info *dmm; struct sr_config *src; GSList *l, *devices; const char *conn, *serialcomm; struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_serial_dev_inst *serial; int dropped, ret; size_t len; uint8_t buf[128]; dmm = (struct dmm_info *)di; 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 = dmm->conn; serial = sr_serial_dev_inst_new(conn, serialcomm); if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; sr_info("Probing serial port %s.", conn); devices = NULL; serial_flush(serial); /* Request a packet if the DMM requires this. */ if (dmm->packet_request) { if ((ret = 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, dmm->packet_size, dmm->packet_valid, 3000, 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 - dmm->packet_size; if (dropped > 2 * dmm->packet_size) sr_warn("Had to drop too much data."); 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(dmm->vendor); sdi->model = g_strdup(dmm->device); devc = g_malloc0(sizeof(struct dev_context)); sr_sw_limits_init(&devc->limits); sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1"); devices = g_slist_append(devices, sdi); scan_cleanup: serial_close(serial); return std_scan_complete(di, devices); }