]> sigrok.org Git - libsigrok.git/commitdiff
serial-lcr: add support for packet request
authorGerhard Sittig <redacted>
Mon, 17 Jun 2019 20:59:25 +0000 (22:59 +0200)
committerGerhard Sittig <redacted>
Thu, 20 Jun 2019 14:45:36 +0000 (16:45 +0200)
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.

src/hardware/serial-lcr/api.c
src/hardware/serial-lcr/protocol.c
src/hardware/serial-lcr/protocol.h

index 5bf5f1840fec14715bfcf21b1a4c2b7494315fe3..0919ae8891f71e580b7b74287adcc4f50edc4311 100644 (file)
@@ -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
index 645769724bb1a4b8d4e81d6ab1a60aae873867ef..e7b2612f56661ed0976f6d4cacc4a2374e740d78 100644 (file)
@@ -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;
 }
index 292a10eae7dafcb1047818d8cb5cec49a798768d..4a6e7f043f840c4e95db50d67bd401bd8fd642b2 100644 (file)
@@ -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);