SR_PRIV int sr_metex14_packet_request(struct sr_serial_dev_inst *serial) { const uint8_t wbuf = 'D'; sr_spew("Requesting DMM packet."); return (serial_write_nonblocking(serial, &wbuf, 1) == 1) ? SR_OK : SR_ERR; }
static const void *hw_dev_info_get(int dev_index, int dev_info_id) { struct sr_dev_inst *sdi; struct context *ctx; const void *info; if (!(sdi = sr_dev_inst_get(genericdmm_dev_insts, dev_index))) { sr_err("genericdmm: sdi was NULL."); return NULL; } if (!(ctx = sdi->priv)) { sr_err("genericdmm: sdi->priv was NULL."); return NULL; } sr_spew("genericdmm: dev_index %d, dev_info_id %d.", dev_index, dev_info_id); switch (dev_info_id) { case SR_DI_INST: info = sdi; sr_spew("genericdmm: Returning sdi."); break; case SR_DI_NUM_PROBES: info = GINT_TO_POINTER(1); sr_spew("genericdmm: Returning number of probes: 1."); break; case SR_DI_PROBE_NAMES: info = probe_names; sr_spew("genericdmm: Returning probenames."); break; case SR_DI_CUR_SAMPLERATE: /* TODO get rid of this */ info = NULL; sr_spew("genericdmm: Returning samplerate: 0."); break; default: /* Unknown device info ID. */ sr_err("genericdmm: Unknown device info ID: %d.", dev_info_id); info = NULL; break; } return info; }
/* This comes in whenever the rotary switch is changed to a new position. * We could use it to determine the major measurement mode, but we already * have the output of CONF? for that, which is more detailed. However * we do need to catch this here, or it'll show up in some other output. */ static int recv_switch(const struct sr_dev_inst *sdi, GMatchInfo *match) { (void)sdi; sr_spew("Switch '%s'.", g_match_info_get_string(match)); return SR_OK; }
/** @private */ SR_PRIV int sr_sessionfile_check(const char *filename) { struct zip *archive; struct zip_file *zf; struct zip_stat zs; uint64_t version; int ret; char s[11]; if (!filename) return SR_ERR_ARG; if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { sr_err("Not a regular file: %s.", filename); return SR_ERR; } if (!(archive = zip_open(filename, 0, NULL))) /* No logging: this can be used just to check if it's * a sigrok session file or not. */ return SR_ERR; /* check "version" */ if (!(zf = zip_fopen(archive, "version", 0))) { sr_dbg("Not a sigrok session file: no version found."); zip_discard(archive); return SR_ERR; } ret = zip_fread(zf, s, sizeof(s) - 1); if (ret < 0) { sr_err("Failed to read version file: %s", zip_file_strerror(zf)); zip_fclose(zf); zip_discard(archive); return SR_ERR; } zip_fclose(zf); s[ret] = '\0'; version = g_ascii_strtoull(s, NULL, 10); if (version == 0 || version > 2) { sr_dbg("Cannot handle sigrok session file version %" PRIu64 ".", version); zip_discard(archive); return SR_ERR; } sr_spew("Detected sigrok session file version %" PRIu64 ".", version); /* read "metadata" */ if (zip_stat(archive, "metadata", 0, &zs) < 0) { sr_dbg("Not a valid sigrok session file."); zip_discard(archive); return SR_ERR; } zip_discard(archive); 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; 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)); }
/** * Send a SCPI command, receive the reply and store the reply in scpi_response. * * @param scpi Previously initialised SCPI device structure. * @param command The SCPI command to send to the device (can be NULL). * @param scpi_response Pointer where to store the SCPI response. * * @return SR_OK on success, SR_ERR* on failure. */ SR_PRIV int sr_scpi_get_string(struct sr_scpi_dev_inst *scpi, const char *command, char **scpi_response) { char buf[256]; int len; GString *response; gint64 laststart; unsigned int elapsed_ms; if (command) if (sr_scpi_send(scpi, command) != SR_OK) return SR_ERR; if (sr_scpi_read_begin(scpi) != SR_OK) return SR_ERR; laststart = g_get_monotonic_time(); response = g_string_new(""); *scpi_response = NULL; while (!sr_scpi_read_complete(scpi)) { len = sr_scpi_read_data(scpi, buf, sizeof(buf)); if (len < 0) { sr_err("Incompletely read SCPI response."); g_string_free(response, TRUE); return SR_ERR; } else if (len > 0) { laststart = g_get_monotonic_time(); } g_string_append_len(response, buf, len); elapsed_ms = (g_get_monotonic_time() - laststart) / 1000; if (elapsed_ms >= scpi->read_timeout_ms) { sr_err("Timed out waiting for SCPI response."); g_string_free(response, TRUE); return SR_ERR; } } /* Get rid of trailing linefeed if present */ if (response->len >= 1 && response->str[response->len - 1] == '\n') g_string_truncate(response, response->len - 1); /* Get rid of trailing carriage return if present */ if (response->len >= 1 && response->str[response->len - 1] == '\r') g_string_truncate(response, response->len - 1); sr_spew("Got response: '%.70s', length %" G_GSIZE_FORMAT ".", response->str, response->len); *scpi_response = g_string_free(response, FALSE); return SR_OK; }
SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data) { struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_serial_dev_inst *serial; int len; (void)fd; if (!(sdi = cb_data)) return TRUE; if (!(devc = sdi->priv)) return TRUE; serial = sdi->conn; if (revents == G_IO_IN) { /* Serial data arrived. */ while (NMADMM_BUFSIZE - devc->buflen - 1 > 0) { len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1); if (len < 1) break; devc->buflen += len; *(devc->buf + devc->buflen) = '\0'; if (*(devc->buf + devc->buflen - 1) == '\n') { /* * TODO: According to specs, should be \r, but * then we'd have to get rid of the \n. */ devc->last_req_pending = FALSE; nma_process_line(sdi); break; } } } if (sr_sw_limits_check(&devc->limits)) { sr_dev_acquisition_stop(sdi); } else { /* Request next package. */ if (devc->last_req_pending) { gint64 elapsed_us = g_get_monotonic_time() - devc->req_sent_at; if (elapsed_us > NMADMM_TIMEOUT_MS * 1000) {/* Timeout! */ sr_spew("Request timeout!"); devc->last_req_pending = FALSE; } } if (!devc->last_req_pending) { if (nma_send_req(sdi, NMADMM_REQ_STATUS, NULL) != SR_OK) return FALSE; } } return TRUE; }
/** * Get a block of data from the LA8. * * @param devc The struct containing private per-device-instance data. Must not * be NULL. devc->ftdic must not be NULL either. * @return SR_OK upon success, or SR_ERR upon errors. */ SR_PRIV int la8_read_block(struct dev_context *devc) { int i, byte_offset, m, mi, p, index, bytes_read; time_t now; /* Note: Caller checked that devc and devc->ftdic != NULL. */ sr_spew("Reading block %d.", devc->block_counter); bytes_read = la8_read(devc, devc->mangled_buf, BS); /* If first block read got 0 bytes, retry until success or timeout. */ if ((bytes_read == 0) && (devc->block_counter == 0)) { do { sr_spew("Reading block 0 (again)."); bytes_read = la8_read(devc, devc->mangled_buf, BS); /* TODO: How to handle read errors here? */ now = time(NULL); } while ((devc->done > now) && (bytes_read == 0)); } /* Check if block read was successful or a timeout occured. */ if (bytes_read != BS) { sr_err("Trigger timed out. Bytes read: %d.", bytes_read); (void) la8_reset(devc); /* Ignore errors. */ return SR_ERR; } /* De-mangle the data. */ sr_spew("Demangling block %d.", devc->block_counter); byte_offset = devc->block_counter * BS; m = byte_offset / (1024 * 1024); mi = m * (1024 * 1024); for (i = 0; i < BS; i++) { p = i & (1 << 0); index = m * 2 + (((byte_offset + i) - mi) / 2) * 16; index += (devc->divcount == 0) ? p : (1 - p); devc->final_buf[index] = devc->mangled_buf[i]; } return SR_OK; }
static int parse_value(const uint8_t *buf, struct es519xx_info *info, float *result) { int i, intval, num_digits; float floatval; num_digits = 4 + ((info->packet_size == 14) ? 1 : 0); /* Bytes 1-4 (or 5): Value (4 or 5 decimal digits) */ if (info->is_ol) { sr_spew("Over limit."); *result = INFINITY; return SR_OK; } else if (info->is_ul) { sr_spew("Under limit."); *result = INFINITY; return SR_OK; } else if (!isdigit(buf[1]) || !isdigit(buf[2]) || !isdigit(buf[3]) || !isdigit(buf[4]) || (num_digits == 5 && !isdigit(buf[5]))) { sr_dbg("Value contained invalid digits: %02x %02x %02x %02x " "(%c %c %c %c).", buf[1], buf[2], buf[3], buf[4], buf[1], buf[2], buf[3], buf[4]); return SR_ERR; } intval = (info->is_digit4) ? 1 : 0; for (i = 0; i < num_digits; i++) intval = 10 * intval + (buf[i + 1] - '0'); /* Apply sign. */ intval *= info->is_sign ? -1 : 1; floatval = (float)intval; /* Note: The decimal point position will be parsed later. */ sr_spew("The display value is %f.", floatval); *result = floatval; return SR_OK; }
/** * Arrange for the reception of another measurement from the DMM. * * This routine is unused in the currently implemented PRINT mode, * where the meter sends measurements to the PC in pre-set intervals, * without the PC's intervention. * * @param[in] serial The serial connection. * * @private */ SR_PRIV int sr_asycii_packet_request(struct sr_serial_dev_inst *serial) { /* * The current implementation assumes that the user pressed * the PRINT button. It has no support to query/trigger packet * reception from the meter. */ (void)serial; sr_spew("NOT requesting DMM packet."); return SR_OK; }
static int scpi_serial_read_data(void *priv, char *buf, int maxlen) { struct scpi_serial *sscpi = priv; int len, ret; len = BUFFER_SIZE - sscpi->count; /* Try to read new data into the buffer if there is space. */ if (len > 0) { ret = serial_read(sscpi->serial, sscpi->buffer + sscpi->read, BUFFER_SIZE - sscpi->count); if (ret < 0) return ret; sscpi->count += ret; if (ret > 0) sr_spew("Read %d bytes into buffer.", ret); } /* Return as many bytes as possible from buffer, excluding any trailing newline. */ if (sscpi->read < sscpi->count) { len = sscpi->count - sscpi->read; if (len > maxlen) len = maxlen; if (sscpi->buffer[sscpi->read + len - 1] == '\n') len--; sr_spew("Returning %d bytes from buffer.", len); memcpy(buf, sscpi->buffer + sscpi->read, len); sscpi->read += len; if (sscpi->read == BUFFER_SIZE) { sr_spew("Resetting buffer."); sscpi->count = 0; sscpi->read = 0; } return len; } return 0; }
static int scpi_usbtmc_libusb_send(void *priv, const char *command) { struct scpi_usbtmc_libusb *uscpi = priv; if (scpi_usbtmc_bulkout(uscpi, DEV_DEP_MSG_OUT, command, strlen(command), EOM) <= 0) return SR_ERR; sr_spew("Successfully sent SCPI command: '%s'.", command); return SR_OK; }
static void log_packet(const uint8_t *buf, int idx) { int i; GString *s; s = g_string_sized_new(100); g_string_printf(s, "Packet: "); for (i = 0; i < center_devs[idx].packet_size; i++) g_string_append_printf(s, "%02x ", buf[i]); sr_spew("%s", s->str); g_string_free(s, TRUE); }
/** USB event source dispatch() method. */ static gboolean usb_source_dispatch(GSource *source, GSourceFunc callback, void *user_data) { struct usb_source *usource; GPollFD *pollfd; unsigned int revents; unsigned int i; gboolean keep; usource = (struct usb_source *)source; revents = 0; /* * This is somewhat arbitrary, but drivers use revents to distinguish * actual I/O from timeouts. When we remove the user timeout from the * driver API, this will no longer be needed. */ for (i = 0; i < usource->pollfds->len; i++) { pollfd = g_ptr_array_index(usource->pollfds, i); revents |= pollfd->revents; } if (revents != 0) sr_spew("%s: revents 0x%.2X", __func__, revents); else sr_spew("%s: timed out", __func__); if (!callback) { sr_err("Callback not set, cannot dispatch event."); return G_SOURCE_REMOVE; } keep = (*(sr_receive_data_callback)callback)(-1, revents, user_data); if (G_LIKELY(keep) && G_LIKELY(!g_source_is_destroyed(source))) { if (usource->timeout_us >= 0) usource->due_us = g_source_get_time(source) + usource->timeout_us; else usource->due_us = INT64_MAX; } return keep; }
SR_PRIV int fluke_receive_data(int fd, int revents, void *cb_data) { struct sr_dev_inst *sdi; struct dev_context *devc; int len; int64_t now, elapsed; (void)fd; if (!(sdi = cb_data)) return TRUE; if (!(devc = sdi->priv)) return TRUE; if (revents == G_IO_IN) { /* Serial data arrived. */ while(FLUKEDMM_BUFSIZE - devc->buflen - 1 > 0) { len = serial_read(devc->serial, devc->buf + devc->buflen, 1); if (len < 1) break; devc->buflen++; *(devc->buf + devc->buflen) = '\0'; if (*(devc->buf + devc->buflen - 1) == '\r') { *(devc->buf + --devc->buflen) = '\0'; handle_line(sdi); break; } } } if (devc->num_samples >= devc->limit_samples) { sdi->driver->dev_acquisition_stop(sdi, cb_data); return TRUE; } now = g_get_monotonic_time() / 1000; elapsed = now - devc->cmd_sent_at; /* Send query command at poll_period interval, or after 1 second * has elapsed. This will make it recover from any out-of-sync * or temporary disconnect issues. */ if ((devc->expect_response == FALSE && elapsed > devc->profile->poll_period) || elapsed > 1000) { sr_spew("Sending QM."); if (serial_write(devc->serial, "QM\r", 3) == -1) sr_err("Unable to send QM: %s.", strerror(errno)); devc->cmd_sent_at = now; devc->expect_response = TRUE; } return TRUE; }
static int parse_value(const uint8_t *buf, struct vc870_info *info, float *result) { int i, intval; float floatval; /* Bytes 3-7: Main display value (5 decimal digits) */ if (info->is_open || info->is_ol1) { sr_spew("Over limit."); *result = INFINITY; return SR_OK; } else if (!isdigit(buf[3]) || !isdigit(buf[4]) || !isdigit(buf[5]) || !isdigit(buf[6]) || !isdigit(buf[7])) { sr_dbg("Invalid digits: %02x %02x %02x %02x %02X " "(%c %c %c %c %c).", buf[3], buf[4], buf[5], buf[6], buf[7], buf[3], buf[4], buf[5], buf[6], buf[7]); return SR_ERR; } intval = 0; for (i = 0; i < 5; i++) intval = 10 * intval + (buf[i + 3] - '0'); /* Main display. */ // intval = 10 * intval + (buf[i + 8] - '0'); /* TODO: Aux display. */ /* Apply sign. */ intval *= info->is_sign1 ? -1 : 1; // intval *= info->is_sign2 ? -1 : 1; /* TODO: Fahrenheit / aux display. */ floatval = (float)intval; /* Note: The decimal point position will be parsed later. */ sr_spew("The display value is %f.", floatval); *result = floatval; return SR_OK; }
static int receive(const struct sr_transform *t, struct sr_datafeed_packet *packet_in, struct sr_datafeed_packet **packet_out) { if (!t || !t->sdi || !packet_in || !packet_out) return SR_ERR_ARG; /* Do nothing, just pass on packets unmodified. */ sr_spew("Received packet of type %d, passing on unmodified.", packet_in->type); *packet_out = packet_in; return SR_OK; }
/** @private */ SR_PRIV int sr_sessionfile_check(const char *filename) { struct stat st; struct zip *archive; struct zip_file *zf; struct zip_stat zs; int version, ret; char s[11]; if (!filename) return SR_ERR_ARG; if (stat(filename, &st) == -1) { sr_err("Couldn't stat %s: %s", filename, g_strerror(errno)); return SR_ERR; } if (!(archive = zip_open(filename, 0, &ret))) /* No logging: this can be used just to check if it's * a sigrok session file or not. */ return SR_ERR; /* check "version" */ if (!(zf = zip_fopen(archive, "version", 0))) { sr_dbg("Not a sigrok session file: no version found."); return SR_ERR; } if ((ret = zip_fread(zf, s, 10)) == -1) return SR_ERR; zip_fclose(zf); s[ret] = 0; version = strtoull(s, NULL, 10); if (version > 2) { sr_dbg("Cannot handle sigrok session file version %d.", version); return SR_ERR; } sr_spew("Detected sigrok session file version %d.", version); /* read "metadata" */ if (zip_stat(archive, "metadata", 0, &zs) == -1) { sr_dbg("Not a valid sigrok session file."); return SR_ERR; } if ((ret = zip_close(archive)) == -1) { sr_dbg("error closing zipfile: %s", zip_strerror(archive)); return SR_ERR; } return SR_OK; }
static int recv_fetc(const struct sr_dev_inst *sdi, GMatchInfo *match) { struct dev_context *devc; struct sr_datafeed_packet packet; struct sr_datafeed_analog_old analog; float fvalue; const char *s; char *mstr; sr_spew("FETC reply '%s'.", g_match_info_get_string(match)); devc = sdi->priv; if (devc->cur_mq == -1) /* Haven't seen configuration yet, so can't know what * the fetched float means. Not really an error, we'll * get metadata soon enough. */ return SR_OK; s = g_match_info_get_string(match); if (!strcmp(s, "-9.90000000E+37") || !strcmp(s, "+9.90000000E+37")) { /* An invalid measurement shows up on the display as "O.L", but * comes through like this. Since comparing 38-digit floats * is rather problematic, we'll cut through this here. */ fvalue = NAN; } else { mstr = g_match_info_fetch(match, 1); if (sr_atof_ascii(mstr, &fvalue) != SR_OK) { g_free(mstr); sr_dbg("Invalid float."); return SR_ERR; } g_free(mstr); if (devc->cur_divider > 0) fvalue /= devc->cur_divider; } memset(&analog, 0, sizeof(struct sr_datafeed_analog_old)); analog.mq = devc->cur_mq; analog.unit = devc->cur_unit; analog.mqflags = devc->cur_mqflags; analog.channels = sdi->channels; analog.num_samples = 1; analog.data = &fvalue; packet.type = SR_DF_ANALOG_OLD; packet.payload = &analog; sr_session_send(devc->cb_data, &packet); devc->num_samples++; return SR_OK; }
static int receive(const struct sr_transform *t, struct sr_datafeed_packet *packet_in, struct sr_datafeed_packet **packet_out) { const struct sr_datafeed_logic *logic; const struct sr_datafeed_analog *analog; struct sr_channel *ch; GSList *l; float *fdata, *f; int si, num_channels, c; uint8_t *b; uint64_t i, j; if (!t || !t->sdi || !packet_in || !packet_out) return SR_ERR_ARG; switch (packet_in->type) { case SR_DF_LOGIC: logic = packet_in->payload; for (i = 0; i <= logic->length - logic->unitsize; i += logic->unitsize) { for (j = 0; j < logic->unitsize; j++) { /* For now invert every bit in every byte. */ b = (uint8_t *)logic->data + i + logic->unitsize - 1 - j; *b = ~(*b); } } break; case SR_DF_ANALOG: analog = packet_in->payload; fdata = (float *)analog->data; num_channels = g_slist_length(analog->channels); for (si = 0; si < analog->num_samples; si++) { /* For now invert all values in all channels. */ for (l = analog->channels, c = 0; l; l = l->next, c++) { ch = l->data; (void)ch; f = &fdata[si * num_channels + c]; *f = 1.0 / *f; } } break; default: sr_spew("Unsupported packet type %d, ignoring.", packet_in->type); break; } /* Return the in-place-modified packet. */ *packet_out = packet_in; return SR_OK; }
/* * Since the 22-812 does not identify itself in any way, shape, or form, * we really don't know for sure who is sending the data. We must use every * possible check to filter out bad packets, especially since detection of the * 22-812 depends on how well we can filter the packets. */ SR_PRIV gboolean sr_rs9lcd_packet_valid(const uint8_t *buf) { const struct rs9lcd_packet *rs_packet = (void *)buf; /* * Check for valid mode first, before calculating the checksum. No * point calculating the checksum, if we know we'll reject the packet. */ if (!(rs_packet->mode < MODE_INVALID)) return FALSE; if (!checksum_valid(rs_packet)) { sr_spew("Packet with invalid checksum. Discarding."); return FALSE; } if (!selection_good(rs_packet)) { sr_spew("Packet with invalid selection bits. Discarding."); return FALSE; } return TRUE; }
static int get_cfg(const struct sr_dev_inst *sdi, char *cmd, char *reply) { int len; if (rigol_ds1xx2_send(sdi, cmd) != SR_OK) return SR_ERR; if ((len = serial_read(sdi->conn, reply, 255)) < 0) return SR_ERR; reply[len] = '\0'; sr_spew("Received '%s'.", reply); return SR_OK; }
static gboolean receive_line(const struct sr_dev_inst *sdi) { struct dev_context *devc; const struct agdmm_recv *recvs, *recv; GRegex *reg; GMatchInfo *match; gboolean stop = FALSE; int i; devc = sdi->priv; /* Strip CRLF */ while (devc->buflen) { if (*(devc->buf + devc->buflen - 1) == '\r' || *(devc->buf + devc->buflen - 1) == '\n') *(devc->buf + --devc->buflen) = '\0'; else break; } sr_spew("Received '%s'.", devc->buf); recv = NULL; recvs = devc->profile->recvs; for (i = 0; (&recvs[i])->recv_regex; i++) { reg = g_regex_new((&recvs[i])->recv_regex, 0, 0, NULL); if (g_regex_match(reg, (char *)devc->buf, 0, &match)) { recv = &recvs[i]; break; } g_match_info_unref(match); g_regex_unref(reg); } if (recv) { enum job_type type = recv->recv(sdi, match); if (type == job_current(devc)->type) job_done(devc); else if (type == JOB_AGAIN) job_again(devc); else if (type == JOB_STOP) stop = TRUE; g_match_info_unref(match); g_regex_unref(reg); } else sr_dbg("Unknown line '%s'.", devc->buf); /* Done with this. */ devc->buflen = 0; return stop; }
static int dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; int ret; int64_t timediff_us, timediff_ms; devc = sdi->priv; /* * If the firmware was recently uploaded, wait up to MAX_RENUM_DELAY_MS * milliseconds for the FX2 to renumerate. */ ret = SR_ERR; if (devc->fw_updated > 0) { sr_info("Waiting for device to reset."); /* Takes >= 300ms for the FX2 to be gone from the USB bus. */ g_usleep(300 * 1000); timediff_ms = 0; while (timediff_ms < MAX_RENUM_DELAY_MS) { if ((ret = logic16_dev_open(sdi)) == SR_OK) break; g_usleep(100 * 1000); timediff_us = g_get_monotonic_time() - devc->fw_updated; timediff_ms = timediff_us / 1000; sr_spew("Waited %" PRIi64 "ms.", timediff_ms); } if (ret != SR_OK) { sr_err("Device failed to renumerate."); return SR_ERR; } sr_info("Device came back after %" PRIi64 "ms.", timediff_ms); } else { sr_info("Firmware upload was not needed."); ret = logic16_dev_open(sdi); } if (ret != SR_OK) { sr_err("Unable to open device."); return SR_ERR; } if (devc->cur_samplerate == 0) { /* Samplerate hasn't been set; default to the slowest one. */ devc->cur_samplerate = samplerates[0]; } return SR_OK; }
/* This comes in whenever the rotary switch is changed to a new position. * We could use it to determine the major measurement mode, but we already * have the output of CONF? for that, which is more detailed. However * we do need to catch this here, or it'll show up in some other output. */ static int recv_switch(const struct sr_dev_inst *sdi, GMatchInfo *match) { struct dev_context *devc = sdi->priv; sr_spew("Switch '%s'.", g_match_info_get_string(match)); devc->current_job = 0; devc->job_running = FALSE; memset(devc->jobs_start, 0, sizeof(devc->jobs_start)); devc->cur_mq[0] = -1; if (devc->profile->nb_channels > 2) devc->cur_mq[1] = -1; return SR_OK; }
static int scpi_serial_read_data(void *priv, char *buf, int maxlen) { struct scpi_serial *sscpi = priv; int ret; /* Try to read new data into the buffer. */ ret = serial_read_nonblocking(sscpi->serial, buf, maxlen); if (ret < 0) return ret; if (ret > 0) { sr_spew("Read %d bytes into buffer.", ret); if (buf[ret - 1] == '\n') { sscpi->got_newline = TRUE; sr_spew("Received terminator"); } else { sscpi->got_newline = FALSE; } } return ret; }
static int dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; struct sr_usb_dev_inst *usb; int64_t timediff_us, timediff_ms; int err; devc = sdi->priv; usb = sdi->conn; /* * If the firmware was recently uploaded, wait up to MAX_RENUM_DELAY_MS * for the FX2 to renumerate. */ err = SR_ERR; if (devc->fw_updated > 0) { sr_info("Waiting for device to reset."); /* Takes >= 300ms for the FX2 to be gone from the USB bus. */ g_usleep(300 * 1000); timediff_ms = 0; while (timediff_ms < MAX_RENUM_DELAY_MS) { if ((err = hantek_6xxx_open(sdi)) == SR_OK) break; g_usleep(100 * 1000); timediff_us = g_get_monotonic_time() - devc->fw_updated; timediff_ms = timediff_us / 1000; sr_spew("Waited %" PRIi64 " ms.", timediff_ms); } if (timediff_ms < MAX_RENUM_DELAY_MS) sr_info("Device came back after %"PRIu64" ms.", timediff_ms); } else { err = hantek_6xxx_open(sdi); } if (err != SR_OK) { sr_err("Unable to open device."); return SR_ERR; } err = libusb_claim_interface(usb->devhdl, USB_INTERFACE); if (err != 0) { sr_err("Unable to claim interface: %s.", libusb_error_name(err)); return SR_ERR; } return SR_OK; }
SR_PRIV void sl2_receive_transfer_out( struct libusb_transfer *transfer) { struct sr_dev_inst *sdi; struct dev_context *devc; int ret = 0; sdi = transfer->user_data; devc = sdi->priv; if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { sr_err("Transfer to device failed: %i.", transfer->status); devc->transfer_error = TRUE; return; } if (sdi->status == SR_ST_STOPPING && !devc->stopping_in_progress) { devc->next_state = STATE_RESET_AND_IDLE; devc->stopping_in_progress = TRUE; if (libusb_submit_transfer(devc->xfer_in) != 0) { sr_err("Submit transfer failed: %s.", libusb_error_name(ret)); devc->transfer_error = TRUE; } return; } if (devc->state != devc->next_state) sr_spew("State changed from %i to %i.", devc->state, devc->next_state); devc->state = devc->next_state; if (devc->state == STATE_IDLE) { stop_acquisition(sdi); } else if (devc->state == STATE_SAMPLE) { devc->next_state = STATE_WAIT_DATA_READY; ret = libusb_submit_transfer(devc->xfer_in); } else if (devc->state == STATE_WAIT_DEVICE_READY) { ret = libusb_submit_transfer(devc->xfer_in); } if (ret != 0) { sr_err("Submit transfer failed: %s.", libusb_error_name(ret)); devc->transfer_error = TRUE; } }
/** USB event source finalize() method. */ static void usb_source_finalize(GSource *source) { struct usb_source *usource; usource = (struct usb_source *)source; sr_spew("%s", __func__); libusb_set_pollfd_notifiers(usource->usb_ctx, NULL, NULL, NULL); g_ptr_array_unref(usource->pollfds); usource->pollfds = NULL; sr_session_source_destroyed(usource->session, usource->usb_ctx, source); }
/** * Read single byte from serial port. * * @retval -1 Timeout or error. * @retval other Byte. */ static int read_byte(struct sr_serial_dev_inst *serial, gint64 timeout) { uint8_t result = 0; int rc = 0; for (;;) { rc = serial_read_nonblocking(serial, &result, 1); if (rc == 1) { sr_spew("read: 0x%02x/%d", result, result); return result; } if (g_get_monotonic_time() > timeout) return -1; g_usleep(2000); } }