From: Gerhard Sittig Date: Wed, 15 Mar 2023 21:46:14 +0000 (+0100) Subject: rdtech-um: migrate from binary helper channel to feed queue X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=1b43eb299e16b049435c20ee36933bffb4144547;p=libsigrok.git rdtech-um: migrate from binary helper channel to feed queue 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. --- diff --git a/src/hardware/rdtech-um/api.c b/src/hardware/rdtech-um/api.c index ce0356e0..363dfe55 100644 --- a/src/hardware/rdtech-um/api.c +++ b/src/hardware/rdtech-um/api.c @@ -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, diff --git a/src/hardware/rdtech-um/protocol.c b/src/hardware/rdtech-um/protocol.c index 333c1e69..25de9ec4 100644 --- a/src/hardware/rdtech-um/protocol.c +++ b/src/hardware/rdtech-um/protocol.c @@ -39,24 +39,24 @@ /* 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; } diff --git a/src/hardware/rdtech-um/protocol.h b/src/hardware/rdtech-um/protocol.h index e501e920..ac147d8c 100644 --- a/src/hardware/rdtech-um/protocol.h +++ b/src/hardware/rdtech-um/protocol.h @@ -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;