static void handle_new_data(struct sr_dev_inst *sdi) { struct dev_context *devc; int len, status, offset = 0; struct sr_serial_dev_inst *serial; devc = sdi->priv; serial = sdi->conn; /* Try to get as much data as the buffer can hold. */ len = DMM_BUFSIZE - devc->buflen; len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len); if (len < 1) { sr_err("Serial port read error: %d.", len); return; } devc->buflen += len; status = PACKET_INVALID_HEADER; /* Now look for packets in that data. */ while (status != PACKET_NEED_MORE_DATA) { /* We don't have a header, look for one. */ if (devc->next_packet_len == 0) { len = devc->buflen - offset; status = brymen_packet_length(devc->buf + offset, &len); if (status == PACKET_HEADER_OK) { /* We know how large the packet will be. */ devc->next_packet_len = len; } else if (status == PACKET_NEED_MORE_DATA) { /* We didn't yet receive the full header. */ devc->next_packet_len = 0; break; } else { /* Invalid header. Move on. */ devc->next_packet_len = 0; offset++; continue; } } /* We know how the packet size, but did we receive all of it? */ if (devc->buflen - offset < devc->next_packet_len) break; /* We should have a full packet here, so we can check it. */ if (brymen_packet_is_valid(devc->buf + offset)) { handle_packet(devc->buf + offset, sdi); offset += devc->next_packet_len; } else { offset++; } /* We are done with this packet. Look for a new one. */ devc->next_packet_len = 0; } /* If we have any data left, move it to the beginning of our buffer. */ memmove(devc->buf, devc->buf + offset, devc->buflen - offset); devc->buflen -= offset; }
static void handle_new_data(struct sr_dev_inst *sdi, int idx) { struct dev_context *devc; struct sr_serial_dev_inst *serial; int len, i, offset = 0; devc = sdi->priv; serial = sdi->conn; /* Try to get as much data as the buffer can hold. */ len = SERIAL_BUFSIZE - devc->buflen; len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len); if (len < 1) { sr_err("Serial port read error: %d.", len); return; } devc->buflen += len; /* Now look for packets in that data. */ while ((devc->buflen - offset) >= mic_devs[idx].packet_size) { if (mic_devs[idx].packet_valid(devc->buf + offset)) { handle_packet(devc->buf + offset, sdi, idx); offset += mic_devs[idx].packet_size; } else { offset++; } } /* If we have any data left, move it to the beginning of our buffer. */ for (i = 0; i < devc->buflen - offset; i++) devc->buf[i] = devc->buf[offset + i]; devc->buflen -= offset; }
SR_PRIV int pce_322a_receive_data(int fd, int revents, void *cb_data) { const struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_serial_dev_inst *serial; unsigned char c; (void)fd; if (!(sdi = cb_data)) return TRUE; if (!(devc = sdi->priv)) return TRUE; if (!(serial = sdi->conn)) return TRUE; if (revents == G_IO_IN) { if (serial_read_nonblocking(serial, &c, 1) != 1) return TRUE; process_byte(sdi, c); } return TRUE; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_config *src; struct sr_serial_dev_inst *serial; struct sr_dev_inst *sdi; GSList *l, *devices; gint64 start; const char *conn; unsigned char c; conn = NULL; for (l = options; l; l = l->next) { src = l->data; if (src->key == SR_CONF_CONN) conn = g_variant_get_string(src->data, NULL); } if (!conn) return NULL; serial = sr_serial_dev_inst_new(conn, SERIALCOMM); if (serial_open(serial, SERIAL_RDONLY) != SR_OK) return NULL; devices = NULL; drvc = di->priv; start = g_get_monotonic_time(); while (g_get_monotonic_time() - start < MAX_SCAN_TIME_US) { if (serial_read_nonblocking(serial, &c, 1) == 1 && c == 0xa5) { /* Found one. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup("CEM"); sdi->model = g_strdup("DT-885x"); devc = g_malloc0(sizeof(struct dev_context)); devc->cur_mqflags = 0; devc->recording = -1; devc->cur_meas_range = 0; devc->cur_data_source = DATA_SOURCE_LIVE; devc->enable_data_source_memory = FALSE; sdi->conn = sr_serial_dev_inst_new(conn, SERIALCOMM); sdi->inst_type = SR_INST_SERIAL; sdi->priv = devc; sdi->driver = di; sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "SPL"); drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); break; } /* It takes about 1ms for a byte to come in. */ g_usleep(1000); } serial_close(serial); return devices; }
SR_PRIV int appa_55ii_receive_data(int fd, int revents, void *cb_data) { struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_serial_dev_inst *serial; int64_t time; const uint8_t *ptr, *next_ptr, *end_ptr; int len; (void)fd; if (!(sdi = cb_data) || !(devc = sdi->priv) || revents != G_IO_IN) return TRUE; serial = sdi->conn; /* Try to get as much data as the buffer can hold. */ len = sizeof(devc->buf) - devc->buf_len; len = serial_read_nonblocking(serial, devc->buf + devc->buf_len, len); if (len < 1) { sr_err("Serial port read error: %d.", len); return FALSE; } devc->buf_len += len; /* Now look for packets in that data. */ ptr = devc->buf; end_ptr = ptr + devc->buf_len; while ((next_ptr = appa_55ii_parse_data(sdi, ptr, end_ptr - ptr))) ptr = next_ptr; /* If we have any data left, move it to the beginning of our buffer. */ memmove(devc->buf, ptr, end_ptr - ptr); devc->buf_len -= ptr - devc->buf; /* If buffer is full and no valid packet was found, wipe buffer. */ if (devc->buf_len >= sizeof(devc->buf)) { devc->buf_len = 0; return FALSE; } if (devc->limit_samples && devc->num_samples >= devc->limit_samples) { sr_info("Requested number of samples reached."); sdi->driver->dev_acquisition_stop(sdi, devc->session_cb_data); return TRUE; } if (devc->limit_msec) { time = (g_get_monotonic_time() - devc->start_time) / 1000; if (time > (int64_t)devc->limit_msec) { sr_info("Requested time limit reached."); sdi->driver->dev_acquisition_stop(sdi, devc->session_cb_data); return TRUE; } } return TRUE; }
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; }
SR_PRIV int fluke_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; int64_t now, elapsed; (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 (FLUKEDMM_BUFSIZE - devc->buflen - 1 > 0) { len = serial_read_nonblocking(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 (sr_sw_limits_check(&devc->limits)) { sdi->driver->dev_acquisition_stop(sdi); 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 easier to recover from any * out-of-sync or temporary disconnect issues. */ if ((devc->expect_response == FALSE && elapsed > devc->profile->poll_period) || elapsed > devc->profile->timeout) { if (serial_write_blocking(serial, "QM\r", 3, SERIAL_WRITE_TIMEOUT_MS) < 0) sr_err("Unable to send QM."); devc->cmd_sent_at = now; devc->expect_response = TRUE; } return TRUE; }
size_t publish_callback(void *p, size_t size, size_t n, void *up) { if (size * n < 1) { return 0; } char buf; if (serial_read_nonblocking((struct serial_device_t *)up, &buf, 1) < 0) { log_error("publish_callback: serial_read_nonblocking"); return 0; } *(char *)p = buf; return 1; }
/** * 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); } }
static void handle_new_data(struct sr_dev_inst *sdi, void *info) { struct dmm_info *dmm; struct dev_context *devc; int len, i, offset = 0; struct sr_serial_dev_inst *serial; dmm = (struct dmm_info *)sdi->driver; devc = sdi->priv; serial = sdi->conn; /* Try to get as much data as the buffer can hold. */ len = DMM_BUFSIZE - devc->buflen; len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len); if (len == 0) return; /* No new bytes, nothing to do. */ if (len < 0) { sr_err("Serial port read error: %d.", len); return; } devc->buflen += len; /* Now look for packets in that data. */ while ((devc->buflen - offset) >= dmm->packet_size) { if (dmm->packet_valid(devc->buf + offset)) { handle_packet(devc->buf + offset, sdi, info); offset += dmm->packet_size; /* Request next packet, if required. */ if (!dmm->packet_request) break; if (dmm->req_timeout_ms || dmm->req_delay_ms) devc->req_next_at = g_get_monotonic_time() + dmm->req_delay_ms * 1000; req_packet(sdi); } else { offset++; } } /* If we have any data left, move it to the beginning of our buffer. */ for (i = 0; i < devc->buflen - offset; i++) devc->buf[i] = devc->buf[offset + i]; devc->buflen -= offset; }
SR_PRIV int teleinfo_receive_data(int fd, int revents, void *cb_data) { struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_serial_dev_inst *serial; const uint8_t *ptr, *next_ptr, *end_ptr; int len; (void)fd; if (!(sdi = cb_data) || !(devc = sdi->priv) || revents != G_IO_IN) return TRUE; serial = sdi->conn; /* Try to get as much data as the buffer can hold. */ len = TELEINFO_BUF_SIZE - devc->buf_len; len = serial_read_nonblocking(serial, devc->buf + devc->buf_len, len); if (len < 1) { sr_err("Serial port read error: %d.", len); return FALSE; } devc->buf_len += len; /* Now look for packets in that data. */ ptr = devc->buf; end_ptr = ptr + devc->buf_len; while ((next_ptr = teleinfo_parse_data(sdi, ptr, end_ptr - ptr, NULL))) ptr = next_ptr; /* If we have any data left, move it to the beginning of our buffer. */ memmove(devc->buf, ptr, end_ptr - ptr); devc->buf_len -= ptr - devc->buf; /* If buffer is full and no valid packet was found, wipe buffer. */ if (devc->buf_len >= TELEINFO_BUF_SIZE) { devc->buf_len = 0; return FALSE; } if (sr_sw_limits_check(&devc->sw_limits)) sdi->driver->dev_acquisition_stop(sdi); return TRUE; }
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_nonblocking(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; }
SR_PRIV int agdmm_receive_data(int fd, int revents, void *cb_data) { struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_serial_dev_inst *serial; gboolean stop = FALSE; 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 (AGDMM_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') { /* End of line */ stop = receive_line(sdi); break; } } } if (sr_sw_limits_check(&devc->limits) || stop) sr_dev_acquisition_stop(sdi); else dispatch(sdi); return TRUE; }
SR_PRIV int agdmm_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 (AGDMM_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') { /* End of line */ receive_line(sdi); break; } } } dispatch(sdi); if (devc->limit_samples && devc->num_samples >= devc->limit_samples) sdi->driver->dev_acquisition_stop(sdi, cb_data); return TRUE; }
static void handle_new_data(struct sr_dev_inst *sdi, void *info) { struct scale_info *scale; struct dev_context *devc; int len, i, offset = 0; struct sr_serial_dev_inst *serial; scale = (struct scale_info *)sdi->driver; devc = sdi->priv; serial = sdi->conn; /* Try to get as much data as the buffer can hold. */ len = SCALE_BUFSIZE - devc->buflen; len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len); if (len == 0) return; /* No new bytes, nothing to do. */ if (len < 0) { sr_err("Serial port read error: %d.", len); return; } devc->buflen += len; /* Now look for packets in that data. */ while ((devc->buflen - offset) >= scale->packet_size) { if (scale->packet_valid(devc->buf + offset)) { handle_packet(devc->buf + offset, sdi, info); offset += scale->packet_size; } else { offset++; } } /* If we have any data left, move it to the beginning of our buffer. */ for (i = 0; i < devc->buflen - offset; i++) devc->buf[i] = devc->buf[offset + i]; devc->buflen -= offset; }
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; }
/** * Try to find a valid packet in a serial data stream. * * @param serial Previously initialized serial port structure. * @param buf Buffer containing the bytes to write. * @param buflen Size of the buffer. * @param[in] packet_size Size, in bytes, of a valid packet. * @param is_valid Callback that assesses whether the packet is valid or not. * @param[in] timeout_ms The timeout after which, if no packet is detected, to * abort scanning. * @param[in] baudrate The baudrate of the serial port. This parameter is not * critical, but it helps fine tune the serial port polling * delay. * * @retval SR_OK Valid packet was found within the given timeout. * @retval SR_ERR Failure. * * @private */ SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial, uint8_t *buf, size_t *buflen, size_t packet_size, packet_valid_callback is_valid, uint64_t timeout_ms, int baudrate) { uint64_t start, time, byte_delay_us; size_t ibuf, i, maxlen; ssize_t len; maxlen = *buflen; sr_dbg("Detecting packets on %s (timeout = %" PRIu64 "ms, baudrate = %d).", serial->port, timeout_ms, baudrate); if (maxlen < (packet_size / 2) ) { sr_err("Buffer size must be at least twice the packet size."); return SR_ERR; } /* Assume 8n1 transmission. That is 10 bits for every byte. */ byte_delay_us = 10 * ((1000 * 1000) / baudrate); start = g_get_monotonic_time(); i = ibuf = len = 0; while (ibuf < maxlen) { len = serial_read_nonblocking(serial, &buf[ibuf], 1); if (len > 0) { ibuf += len; } else if (len == 0) { /* No logging, already done in serial_read(). */ } else { /* Error reading byte, but continuing anyway. */ } time = g_get_monotonic_time() - start; time /= 1000; if ((ibuf - i) >= packet_size) { /* We have at least a packet's worth of data. */ if (is_valid(&buf[i])) { sr_spew("Found valid %zu-byte packet after " "%" PRIu64 "ms.", (ibuf - i), time); *buflen = ibuf; return SR_OK; } else { sr_spew("Got %zu bytes, but not a valid " "packet.", (ibuf - i)); } /* Not a valid packet. Continue searching. */ i++; } if (time >= timeout_ms) { /* Timeout */ sr_dbg("Detection timed out after %" PRIu64 "ms.", time); break; } if (len < 1) g_usleep(byte_delay_us); } *buflen = ibuf; sr_err("Didn't find a valid packet (read %zu bytes).", *buflen); return SR_ERR; }
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; gboolean terminating; gdouble elapsed_s; (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 number of samples or time limit reached, stop acquisition. */ terminating = FALSE; if (devc->limit_samples && (devc->num_samples >= devc->limit_samples)) { sdi->driver->dev_acquisition_stop(sdi, cb_data); terminating = TRUE; } if (devc->limit_msec) { elapsed_s = g_timer_elapsed(devc->elapsed_msec, NULL); if ((elapsed_s * 1000) >= devc->limit_msec) { sdi->driver->dev_acquisition_stop(sdi, cb_data); terminating = TRUE; } } /* Request next package. */ if (!terminating) { 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; }
/** * Try to find a valid packet in a serial data stream. * * @param serial Previously initialized serial port structure. * @param buf Buffer containing the bytes to write. * @param buflen Size of the buffer. * @param get_packet_size Callback that assesses the size of incoming packets. * @param is_valid Callback that assesses whether the packet is valid or not. * @param timeout_ms The timeout after which, if no packet is detected, to * abort scanning. * @param baudrate The baudrate of the serial port. This parameter is not * critical, but it helps fine tune the serial port polling * delay. * * @return SR_OK if a valid packet is found within the given timeout, * SR_ERR upon failure. */ SR_PRIV int brymen_stream_detect(struct sr_serial_dev_inst *serial, uint8_t *buf, size_t *buflen, packet_length_t get_packet_size, packet_valid_callback is_valid, uint64_t timeout_ms, int baudrate) { int64_t start, time, byte_delay_us; size_t ibuf, i, maxlen; int status, len, packet_len, stream_len; maxlen = *buflen; sr_dbg("Detecting packets on %s (timeout = %" PRIu64 "ms, baudrate = %d).", serial->port, timeout_ms, baudrate); /* Assume 8n1 transmission. That is 10 bits for every byte. */ byte_delay_us = 10 * ((1000 * 1000) / baudrate); start = g_get_monotonic_time(); packet_len = i = ibuf = len = 0; while (ibuf < maxlen) { len = serial_read_nonblocking(serial, &buf[ibuf], maxlen - ibuf); if (len > 0) { ibuf += len; sr_spew("Read %d bytes.", len); } time = g_get_monotonic_time() - start; time /= 1000; stream_len = ibuf - i; if (stream_len > 0 && packet_len == 0) { /* How large of a packet are we expecting? */ packet_len = stream_len; status = get_packet_size(&buf[i], &packet_len); switch (status) { case PACKET_HEADER_OK: /* We know how much data we need to wait for. */ break; case PACKET_NEED_MORE_DATA: /* We did not receive the full header. */ packet_len = 0; break; case PACKET_INVALID_HEADER: default: /* * We had enough data, but here was an error in * parsing the header. Restart parsing from the * next byte. */ packet_len = 0; i++; break; } } if ((stream_len >= packet_len) && (packet_len != 0)) { /* We have at least a packet's worth of data. */ if (is_valid(&buf[i])) { sr_spew("Found valid %d-byte packet after " "%" PRIu64 "ms.", packet_len, time); *buflen = ibuf; return SR_OK; } else { sr_spew("Got %d bytes, but not a valid " "packet.", packet_len); } /* Not a valid packet. Continue searching. */ i++; packet_len = 0; } if (time >= (int64_t)timeout_ms) { /* Timeout */ sr_dbg("Detection timed out after %dms.", time); break; } g_usleep(byte_delay_us); } *buflen = ibuf; sr_err("Didn't find a valid packet (read %d bytes).", ibuf); return SR_ERR; }
SR_PRIV int motech_lps_30x_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; gdouble elapsed_s; (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 (LINELEN_MAX - devc->buflen - 2 > 0) { len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1); if (len < 1) break; /* Eliminate whitespace at beginning of line. */ if (g_ascii_isspace(devc->buf[0])) { devc->buf[0] = '\0'; devc->buflen = 0; continue; } devc->buflen += len; devc->buf[devc->buflen] = '\0'; /* If line complete, process msg. */ if ((devc->buflen > 0) && ((devc->buf[devc->buflen-1] == '\r') || devc->buf[devc->buflen-1] == '\n')) { devc->buflen--; devc->buf[devc->buflen] = '\0'; sr_spew("Line complete: \"%s\"", devc->buf); process_line(sdi); } } } /* If number of samples or time limit reached, stop acquisition. */ if (devc->limit_samples && (devc->num_samples >= devc->limit_samples)) sdi->driver->dev_acquisition_stop(sdi, cb_data); if (devc->limit_msec) { elapsed_s = g_timer_elapsed(devc->elapsed_msec, NULL); if ((elapsed_s * 1000) >= devc->limit_msec) sdi->driver->dev_acquisition_stop(sdi, cb_data); } /* Only request the next packet if required. */ if (!((sdi->status == SR_ST_ACTIVE) && (devc->acq_running))) return TRUE; if (devc->acq_req_pending) { int64_t elapsed_us = g_get_monotonic_time() - devc->req_sent_at; if (elapsed_us > (REQ_TIMEOUT_MS * 1000)) { sr_spew("Request timeout: req=%d t=%" PRIi64 "us", (int)devc->acq_req, elapsed_us); devc->acq_req_pending = 0; } } if (devc->acq_req_pending == 0) { switch (devc->acq_req) { case AQ_NONE: /* Fall through */ case AQ_STATUS: devc->acq_req = AQ_U1; lps_send_req(serial, "VOUT1"); break; case AQ_U1: devc->acq_req = AQ_I1; lps_send_req(serial, "IOUT1"); break; case AQ_I1: if (devc->model->num_channels == 1) { devc->acq_req = AQ_STATUS; lps_send_req(serial, "STATUS"); } else { devc->acq_req = AQ_U2; lps_send_req(serial, "VOUT2"); } break; case AQ_U2: devc->acq_req = AQ_I2; lps_send_req(serial, "IOUT2"); break; case AQ_I2: devc->acq_req = AQ_STATUS; lps_send_req(serial, "STATUS"); break; default: sr_err("Illegal devc->acq_req=%d", devc->acq_req); return SR_ERR; } devc->req_sent_at = g_get_real_time(); devc->acq_req_pending = 1; } return TRUE; }
static GSList *scan(GSList *options, int modelid) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; struct sr_config *src; struct sr_channel *ch; struct sr_channel_group *cg; struct sr_serial_dev_inst *serial; GSList *l, *devices; struct pps_model *model; uint8_t packet[PACKET_SIZE]; unsigned int i; int ret; const char *conn, *serialcomm; char channel[10]; devices = NULL; drvc = di->priv; drvc->instances = NULL; conn = serialcomm = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; case SR_CONF_SERIALCOMM: serialcomm = g_variant_get_string(src->data, NULL); break; } } if (!conn) return NULL; if (!serialcomm) serialcomm = SERIALCOMM; if (!(serial = sr_serial_dev_inst_new(conn, serialcomm))) return NULL; if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK) return NULL; serial_flush(serial); /* This is how the vendor software channels for hardware. */ memset(packet, 0, PACKET_SIZE); packet[0] = 0xaa; packet[1] = 0xaa; if (serial_write(serial, packet, PACKET_SIZE) == -1) { sr_err("Unable to write while probing for hardware: %s", strerror(errno)); return NULL; } /* The device responds with a 24-byte packet when it receives a packet. * At 9600 baud, 300ms is long enough for it to have arrived. */ g_usleep(300 * 1000); memset(packet, 0, PACKET_SIZE); if ((ret = serial_read_nonblocking(serial, packet, PACKET_SIZE)) < 0) { sr_err("Unable to read while probing for hardware: %s", strerror(errno)); return NULL; } if (ret != PACKET_SIZE || packet[0] != 0xaa || packet[1] != 0xaa) { /* Doesn't look like an Atten PPS. */ return NULL; } model = NULL; for (i = 0; i < ARRAY_SIZE(models); i++) { if (models[i].modelid == modelid) { model = &models[i]; break; } } if (!model) { sr_err("Unknown modelid %d", modelid); return NULL; } sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, "Atten", model->name, NULL); sdi->driver = di; sdi->inst_type = SR_INST_SERIAL; sdi->conn = serial; for (i = 0; i < MAX_CHANNELS; i++) { snprintf(channel, 10, "CH%d", i + 1); ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE, channel); sdi->channels = g_slist_append(sdi->channels, ch); cg = g_malloc(sizeof(struct sr_channel_group)); cg->name = g_strdup(channel); cg->channels = g_slist_append(NULL, ch); cg->priv = NULL; sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); } devc = g_malloc0(sizeof(struct dev_context)); devc->model = model; devc->config = g_malloc0(sizeof(struct per_channel_config) * model->num_channels); sdi->priv = devc; drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); serial_close(serial); if (!devices) sr_serial_dev_inst_free(serial); return devices; }