]> sigrok.org Git - libsigrok.git/commitdiff
rdtech-um: migrate from binary helper channel to feed queue
authorGerhard Sittig <redacted>
Wed, 15 Mar 2023 21:46:14 +0000 (22:46 +0100)
committerGerhard Sittig <redacted>
Thu, 16 Mar 2023 13:29:30 +0000 (14:29 +0100)
Use common feed queue support for the submission of analog values to the
sigrok session. This leaves the extraction of the value from binary data
images with a factor of 1 for binary helpers, but uses existing code to
scale the value (which operates at higher accuracy) and to submit values
to the sigrok session.

It's up to debate whether a scaling factor value of { 10, 1000, } can be
recognized as 10mV by readers, and how this phrase relates to the other
spec of 2 significant digits. Might be acceptable. Offsetting and MQ flags
are not used by this driver. The exponent representation was used in the
channels table because some models support 100uA resolution for current.
Engineering exponents are preferred for readability (rationals are not
"normalized" to scientific presentation with "odd" exponent values).

Register a device clear routine so that the driver releases resources
that were allocated during scan and device instance creation.

src/hardware/rdtech-um/api.c
src/hardware/rdtech-um/protocol.c
src/hardware/rdtech-um/protocol.h

index ce0356e03248610b9a2c27dc3a87c37514cbab80..363dfe55c53bf63907d4a3bdd24ddf076da5dc7b 100644 (file)
@@ -55,7 +55,9 @@ static GSList *rdtech_um_scan(struct sr_dev_driver *di,
        struct dev_context *devc;
        struct sr_dev_inst *sdi;
        size_t ch_idx;
-       const char *name;
+       const struct rdtech_um_channel_desc *pch;
+       struct sr_channel *ch;
+       struct feed_queue_analog *feed;
 
        serial = sr_serial_dev_inst_new(conn, serialcomm);
        if (serial_open(serial, SERIAL_RDWR) != SR_OK)
@@ -80,9 +82,15 @@ static GSList *rdtech_um_scan(struct sr_dev_driver *di,
        sdi->inst_type = SR_INST_SERIAL;
        sdi->conn = serial;
 
+       devc->feeds = g_malloc0(p->channel_count * sizeof(devc->feeds[0]));
        for (ch_idx = 0; ch_idx < p->channel_count; ch_idx++) {
-               name = p->channels[ch_idx].name;
-               sr_channel_new(sdi, ch_idx, SR_CHANNEL_ANALOG, TRUE, name);
+               pch = &p->channels[ch_idx];
+               ch = sr_channel_new(sdi, ch_idx,
+                       SR_CHANNEL_ANALOG, TRUE, pch->name);
+               feed = feed_queue_analog_alloc(sdi, 1, pch->digits, ch);
+               feed_queue_analog_mq_unit(feed, pch->mq, 0, pch->unit);
+               feed_queue_analog_scale_offset(feed, &pch->scale, NULL);
+               devc->feeds[ch_idx] = feed;
        }
 
        devices = g_slist_append(NULL, sdi);
@@ -100,6 +108,27 @@ err_out:
        return NULL;
 }
 
+static void clear_helper(struct dev_context *devc)
+{
+       const struct rdtech_um_profile *p;
+       size_t ch_idx;
+
+       if (!devc)
+               return;
+
+       p = devc->profile;
+       if (p && devc->feeds) {
+               for (ch_idx = 0; ch_idx < p->channel_count; ch_idx++)
+                       feed_queue_analog_free(devc->feeds[ch_idx]);
+               g_free(devc->feeds);
+       }
+}
+
+static int dev_clear(const struct sr_dev_driver *di)
+{
+       return std_dev_clear_with_callback(di, (std_dev_clear_callback)clear_helper);
+}
+
 static GSList *scan(struct sr_dev_driver *di, GSList *options)
 {
        const char *conn;
@@ -156,7 +185,7 @@ static struct sr_dev_driver rdtech_um_driver_info = {
        .cleanup = std_cleanup,
        .scan = scan,
        .dev_list = std_dev_list,
-       .dev_clear = std_dev_clear,
+       .dev_clear = dev_clear,
        .config_get = NULL,
        .config_set = config_set,
        .config_list = config_list,
index 333c1e69a5f871f102f3aad26ec6cea3cf1c2bf7..25de9ec41ea5d91d9a828eecd604ebf34a304624 100644 (file)
 /* Command code to request another poll response. */
 #define UM_CMD_POLL 0xf0
 
-static const struct binary_analog_channel default_channels[] = {
-       { "V", { 2, BVT_BE_UINT16, 0.01, }, 2, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
-       { "I", { 4, BVT_BE_UINT16, 0.001, }, 3, SR_MQ_CURRENT, SR_UNIT_AMPERE },
-       { "D+", { 96, BVT_BE_UINT16, 0.01, }, 2, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
-       { "D-", { 98, BVT_BE_UINT16, 0.01, }, 2, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
-       { "T", { 10, BVT_BE_UINT16, 1.0, }, 0, SR_MQ_TEMPERATURE, SR_UNIT_CELSIUS },
+static const struct rdtech_um_channel_desc default_channels[] = {
+       { "V", { 2, BVT_BE_UINT16, 1, }, { 10, 1e3, }, 2, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
+       { "I", { 4, BVT_BE_UINT16, 1, }, { 1, 1e3, }, 3, SR_MQ_CURRENT, SR_UNIT_AMPERE },
+       { "D+", { 96, BVT_BE_UINT16, 1, }, { 10, 1e3, }, 2, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
+       { "D-", { 98, BVT_BE_UINT16, 1, }, { 10, 1e3, }, 2, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
+       { "T", { 10, BVT_BE_UINT16, 1, }, { 1, 1, }, 0, SR_MQ_TEMPERATURE, SR_UNIT_CELSIUS },
        /* Threshold-based recording (mWh) */
-       { "E", { 106, BVT_BE_UINT32, 0.001, }, 3, SR_MQ_ENERGY, SR_UNIT_WATT_HOUR },
+       { "E", { 106, BVT_BE_UINT32, 1, }, { 1, 1e3, }, 3, SR_MQ_ENERGY, SR_UNIT_WATT_HOUR },
 };
 
-static const struct binary_analog_channel um25c_channels[] = {
-       { "V", { 2, BVT_BE_UINT16, 0.001, }, 3, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
-       { "I", { 4, BVT_BE_UINT16, 0.0001, }, 4, SR_MQ_CURRENT, SR_UNIT_AMPERE },
-       { "D+", { 96, BVT_BE_UINT16, 0.01, }, 2, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
-       { "D-", { 98, BVT_BE_UINT16, 0.01, }, 2, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
-       { "T", { 10, BVT_BE_UINT16, 1.0, }, 0, SR_MQ_TEMPERATURE, SR_UNIT_CELSIUS },
+static const struct rdtech_um_channel_desc um25c_channels[] = {
+       { "V", { 2, BVT_BE_UINT16, 1, }, { 1, 1e3, }, 3, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
+       { "I", { 4, BVT_BE_UINT16, 1, }, { 100, 1e6, }, 4, SR_MQ_CURRENT, SR_UNIT_AMPERE },
+       { "D+", { 96, BVT_BE_UINT16, 1, }, { 10, 1e3, }, 2, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
+       { "D-", { 98, BVT_BE_UINT16, 1, }, { 10, 1e3, }, 2, SR_MQ_VOLTAGE, SR_UNIT_VOLT },
+       { "T", { 10, BVT_BE_UINT16, 1, }, { 1, 1, }, 0, SR_MQ_TEMPERATURE, SR_UNIT_CELSIUS },
        /* Threshold-based recording (mWh) */
-       { "E", { 106, BVT_BE_UINT32, 0.001, }, 3, SR_MQ_ENERGY, SR_UNIT_WATT_HOUR },
+       { "E", { 106, BVT_BE_UINT32, 1, }, { 1, 1e3, }, 3, SR_MQ_ENERGY, SR_UNIT_WATT_HOUR },
 };
 
 static gboolean csum_ok_fff1(const uint8_t *buf, size_t len)
@@ -191,7 +191,7 @@ static int process_data(struct sr_dev_inst *sdi,
        struct dev_context *devc;
        const struct rdtech_um_profile *p;
        size_t ch_idx;
-       GSList *ch;
+       float v;
        int ret;
 
        devc = sdi->priv;
@@ -208,12 +208,11 @@ static int process_data(struct sr_dev_inst *sdi,
                return SR_ERR_DATA;
        }
 
-       ch_idx = 0;
-       for (ch = sdi->channels; ch; ch = g_slist_next(ch)) {
-               ret = bv_send_analog_channel(sdi, ch->data,
-                       &devc->profile->channels[ch_idx],
-                       data, dlen);
-               ch_idx++;
+       for (ch_idx = 0; ch_idx < p->channel_count; ch_idx++) {
+               ret = bv_get_value(&v, &p->channels[ch_idx].spec, data, dlen);
+               if (ret != SR_OK)
+                       return ret;
+               ret = feed_queue_analog_submit(devc->feeds[ch_idx], v, 1);
                if (ret != SR_OK)
                        return ret;
        }
index e501e920861037955e91a96ecd1257edcda7bff7..ac147d8c026af5eca945103aa3c47a02862caad2 100644 (file)
@@ -33,11 +33,19 @@ enum rdtech_um_model_id {
        RDTECH_UM34C = 0x0d4c,
 };
 
-/* Supported device profiles */
+struct rdtech_um_channel_desc {
+       const char *name;
+       struct binary_value_spec spec;
+       struct sr_rational scale;
+       int digits;
+       enum sr_mq mq;
+       enum sr_unit unit;
+};
+
 struct rdtech_um_profile {
        const char *model_name;
        enum rdtech_um_model_id model_id;
-       const struct binary_analog_channel *channels;
+       const struct rdtech_um_channel_desc *channels;
        size_t channel_count;
        gboolean (*csum_ok)(const uint8_t *buf, size_t len);
 };
@@ -45,6 +53,7 @@ struct rdtech_um_profile {
 struct dev_context {
        const struct rdtech_um_profile *profile;
        struct sr_sw_limits limits;
+       struct feed_queue_analog **feeds;
        uint8_t buf[RDTECH_UM_BUFSIZE];
        size_t buflen;
        int64_t cmd_sent_at;