From: Gerhard Sittig Date: Mon, 17 Jun 2019 20:59:25 +0000 (+0200) Subject: serial-lcr: add support for packet request X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=cb5cd1538f5d;p=libsigrok.git serial-lcr: add support for packet request Some meters require the reception of a request before they provide acquisition data. Add support for the chip driver's .packet_request() routine, and timeout handling in the serial-lcr driver. This follows the serial-dmm model. --- diff --git a/src/hardware/serial-lcr/api.c b/src/hardware/serial-lcr/api.c index 5bf5f184..0919ae88 100644 --- a/src/hardware/serial-lcr/api.c +++ b/src/hardware/serial-lcr/api.c @@ -135,8 +135,15 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) * send data periodically. So we check if the packets match the * probed device's expected format. */ - serial_flush(serial); devices = NULL; + serial_flush(serial); + if (lcr->packet_request) { + ret = lcr->packet_request(serial); + if (ret < 0) { + sr_err("Failed to request packet: %d.", ret); + goto scan_cleanup; + } + } len = sizeof(buf); ret = serial_stream_detect(serial, buf, &len, lcr->packet_size, lcr->packet_valid, 3000); @@ -329,6 +336,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) }, \ vendor, model, ES51919_CHANNEL_COUNT, NULL, \ ES51919_COMM_PARAM, ES51919_PACKET_SIZE, \ + 0, NULL, \ es51919_packet_valid, es51919_packet_parse, \ NULL, NULL, es51919_config_list, \ }).di diff --git a/src/hardware/serial-lcr/protocol.c b/src/hardware/serial-lcr/protocol.c index 64576972..e7b2612f 100644 --- a/src/hardware/serial-lcr/protocol.c +++ b/src/hardware/serial-lcr/protocol.c @@ -148,10 +148,42 @@ static int handle_new_data(struct sr_dev_inst *sdi) return SR_OK; } +static int handle_timeout(struct sr_dev_inst *sdi) +{ + struct dev_context *devc; + const struct lcr_info *lcr; + struct sr_serial_dev_inst *serial; + int64_t now; + int ret; + + devc = sdi->priv; + lcr = devc->lcr_info; + + if (!lcr->packet_request) + return SR_OK; + + now = g_get_monotonic_time(); + if (devc->req_next_at && now < devc->req_next_at) + return SR_OK; + + serial = sdi->conn; + ret = lcr->packet_request(serial); + if (ret < 0) { + sr_err("Failed to request packet: %d.", ret); + return ret; + } + + if (lcr->req_timeout_ms) + devc->req_next_at = now + lcr->req_timeout_ms * 1000; + + return SR_OK; +} + SR_PRIV int lcr_receive_data(int fd, int revents, void *cb_data) { struct sr_dev_inst *sdi; struct dev_context *devc; + int ret; (void)fd; @@ -161,10 +193,13 @@ SR_PRIV int lcr_receive_data(int fd, int revents, void *cb_data) return TRUE; if (revents == G_IO_IN) - handle_new_data(sdi); - + ret = handle_new_data(sdi); + else + ret = handle_timeout(sdi); if (sr_sw_limits_check(&devc->limits)) sr_dev_acquisition_stop(sdi); + if (ret != SR_OK) + return FALSE; return TRUE; } diff --git a/src/hardware/serial-lcr/protocol.h b/src/hardware/serial-lcr/protocol.h index 292a10ea..4a6e7f04 100644 --- a/src/hardware/serial-lcr/protocol.h +++ b/src/hardware/serial-lcr/protocol.h @@ -36,6 +36,8 @@ struct lcr_info { const char **channel_formats; const char *comm; size_t packet_size; + int64_t req_timeout_ms; + int (*packet_request)(struct sr_serial_dev_inst *serial); gboolean (*packet_valid)(const uint8_t *pkt); int (*packet_parse)(const uint8_t *pkt, float *value, struct sr_datafeed_analog *analog, void *info); @@ -60,6 +62,7 @@ struct dev_context { struct lcr_parse_info parse_info; uint64_t output_freq; const char *circuit_model; + int64_t req_next_at; }; SR_PRIV int lcr_receive_data(int fd, int revents, void *cb_data);