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)); }
uint8_t read_path(uint16_t *length_p, coord_t *path_p[]) { // the line to be read, and it size const uint8_t line_size = 40; char line[line_size]; uint16_t bytes_read; // the field extracted const uint8_t field_size = 20; char field[field_size]; uint16_t field_index; int32_t field_value; *length_p = 0; *path_p = 0; // reset the error code path_errno = 0; while ( ! Serial.available() ) { }; uint16_t max_path_size = (AVAIL_MEM - 256) / sizeof(coord_t); #ifdef DEBUG_PATH Serial.print("Max path length "); Serial.println(max_path_size); #endif bytes_read = serial_readline(line, line_size); // read the number of points, first field field_index = 0; field_index = string_read_field(line, field_index, field, field_size, " "); field_value = string_get_int(field); #ifdef DEBUG_PATH Serial.print("Path length "); Serial.print(field_value); Serial.println(); #endif // do a consistency check if ( field_value < 0 || max_path_size < field_value ) { path_errno = 1; return 0; } uint8_t tmp_length = field_value; *length_p = tmp_length; // allocate the storage, see if we got it. coord_t *tmp_path = (coord_t *) malloc( tmp_length * sizeof(coord_t)); if ( !tmp_path ) { path_errno = 2; return 0; } *path_p = tmp_path; while ( tmp_length > 0 ) { bytes_read = serial_readline(line, line_size); // read the number of points, first field field_index = 0; field_index = string_read_field(line, field_index, field, field_size, " "); tmp_path->lat = string_get_int(field); field_index = string_read_field(line, field_index, field, field_size, " "); tmp_path->lon = string_get_int(field); tmp_length--; tmp_path++; } return 1; }
static GSList *scan(GSList *options) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; struct sr_config *src; struct sr_channel *ch; 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) != SR_OK) return NULL; serial_flush(serial); if (serial_write_blocking(serial, "*IDN?\r\n", 7, SERIAL_WRITE_TIMEOUT_MS) < 7) { sr_err("Unable to send identification string."); return NULL; } len = 128; if (!(buf = g_try_malloc(len))) { sr_err("Serial buffer malloc failed."); return NULL; } serial_readline(serial, &buf, &len, 250); 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; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("Agilent"); sdi->model = g_strdup(tokens[1]); sdi->version = g_strdup(tokens[3]); devc = g_malloc0(sizeof(struct dev_context)); devc->profile = &supported_agdmm[i]; devc->cur_mq = -1; sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; sdi->driver = di; ch = sr_channel_new(0, SR_CHANNEL_ANALOG, TRUE, "P1"); sdi->channels = g_slist_append(sdi->channels, ch); 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 *fluke_scan(const char *conn, const char *serialcomm) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; struct sr_channel *ch; struct sr_serial_dev_inst *serial; GSList *devices; int retry, len, i, s; char buf[128], *b, **tokens; if (!(serial = sr_serial_dev_inst_new(conn, serialcomm))) return NULL; if (serial_open(serial, SERIAL_RDWR) != SR_OK) return NULL; drvc = di->priv; b = buf; retry = 0; devices = NULL; /* We'll try the discovery sequence three times in case the device * is not in an idle state when we send ID. */ while (!devices && retry < 3) { retry++; serial_flush(serial); if (serial_write_blocking(serial, "ID\r", 3, SERIAL_WRITE_TIMEOUT_MS) < 0) { sr_err("Unable to send ID string"); continue; } /* Response is first a CMD_ACK byte (ASCII '0' for OK, * or '1' to signify an error. */ len = 128; serial_readline(serial, &b, &len, 150); if (len != 1) continue; if (buf[0] != '0') continue; /* If CMD_ACK was OK, ID string follows. */ len = 128; serial_readline(serial, &b, &len, 850); if (len < 10) continue; if (strcspn(buf, ",") < 15) /* Looks like it's comma-separated. */ tokens = g_strsplit(buf, ",", 3); else /* Fluke 199B, at least, uses semicolon. */ tokens = g_strsplit(buf, ";", 3); if (!strncmp("FLUKE", tokens[0], 5) && tokens[1] && tokens[2]) { for (i = 0; supported_flukedmm[i].model; i++) { if (strcmp(supported_flukedmm[i].modelname, tokens[0] + 6)) continue; /* Skip leading spaces in version number. */ for (s = 0; tokens[1][s] == ' '; s++); sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("Fluke"); sdi->model = g_strdup(tokens[0] + 6); sdi->version = g_strdup(tokens[1] + s); devc = g_malloc0(sizeof(struct dev_context)); devc->profile = &supported_flukedmm[i]; sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; sdi->priv = devc; sdi->driver = di; ch = sr_channel_new(0, SR_CHANNEL_ANALOG, TRUE, "P1"); sdi->channels = g_slist_append(sdi->channels, ch); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); break; } } g_strfreev(tokens); if (devices) /* Found one. */ break; } serial_close(serial); if (!devices) sr_serial_dev_inst_free(serial); 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 *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; }