From: Bartosz Golaszewski Date: Tue, 30 Jun 2015 13:07:50 +0000 (+0200) Subject: baylibre-acme: Add a workaround for slow data acquisition. X-Git-Tag: libsigrok-0.4.0~471 X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=commitdiff_plain;h=7e5a048ff26d516291c3d382c7d70bdbf42628d3;hp=a0648b1a12699429d8a70b8eeb05942885bd32b3 baylibre-acme: Add a workaround for slow data acquisition. At high sampling rates and maximum channels we are not able to acquire samples fast enough, even though frontends still think that samples arrive on time. This causes visible shifts in frontend plots. To compensate for the delay introduce the following workaround: check if we are late (if any clock events have been missed) and resend the last frame n times (n == number of missed clock events). Signed-off-by: Bartosz Golaszewski --- diff --git a/src/hardware/baylibre-acme/protocol.c b/src/hardware/baylibre-acme/protocol.c index 5552ff56..8e730f15 100644 --- a/src/hardware/baylibre-acme/protocol.c +++ b/src/hardware/baylibre-acme/protocol.c @@ -34,6 +34,7 @@ struct channel_group_priv { struct channel_priv { int ch_type; int fd; + float val; struct channel_group_priv *probe; }; @@ -566,9 +567,10 @@ SR_PRIV int bl_acme_receive_data(int fd, int revents, void *cb_data) struct sr_datafeed_analog analog; struct sr_dev_inst *sdi; struct sr_channel *ch; + struct channel_priv *chp; struct dev_context *devc; GSList *chl, chonly; - float valf; + unsigned i; (void)fd; (void)revents; @@ -584,7 +586,6 @@ SR_PRIV int bl_acme_receive_data(int fd, int revents, void *cb_data) packet.type = SR_DF_ANALOG; packet.payload = &analog; memset(&analog, 0, sizeof(struct sr_datafeed_analog)); - analog.data = &valf; if (read(devc->timer_fd, &nrexpiration, sizeof(nrexpiration)) < 0) { sr_warn("Failed to read timer information"); @@ -598,31 +599,53 @@ SR_PRIV int bl_acme_receive_data(int fd, int revents, void *cb_data) if (nrexpiration > 1) devc->samples_missed += nrexpiration - 1; - framep.type = SR_DF_FRAME_BEGIN; - sr_session_send(cb_data, &framep); - /* - * Due to different units used in each channel we're sending - * samples one-by-one. + * XXX This is a nasty workaround... + * + * At high sampling rates and maximum channels we are not able to + * acquire samples fast enough, even though frontends still think + * that samples arrive on time. This causes shifts in frontend + * plots. + * + * To compensate for the delay we check if any clock events were + * missed and - if so - don't really read the next value, but send + * the same sample as fast as possible. We do it until we are back + * on schedule. + * + * At high sampling rate this doesn't seem to visibly reduce the + * accuracy. */ - for (chl = sdi->channels; chl; chl = chl->next) { - ch = chl->data; - if (!ch->enabled) - continue; - chonly.next = NULL; - chonly.data = ch; - analog.channels = &chonly; - analog.num_samples = 1; - analog.mq = channel_to_mq(chl->data); - analog.unit = channel_to_unit(ch); - - valf = read_sample(ch); - - sr_session_send(cb_data, &packet); - } + for (i = 0; i < nrexpiration; i++) { + framep.type = SR_DF_FRAME_BEGIN; + sr_session_send(cb_data, &framep); + + /* + * Due to different units used in each channel we're sending + * samples one-by-one. + */ + for (chl = sdi->channels; chl; chl = chl->next) { + ch = chl->data; + chp = ch->priv; - framep.type = SR_DF_FRAME_END; - sr_session_send(cb_data, &framep); + if (!ch->enabled) + continue; + chonly.next = NULL; + chonly.data = ch; + analog.channels = &chonly; + analog.num_samples = 1; + analog.mq = channel_to_mq(chl->data); + analog.unit = channel_to_unit(ch); + + if (i < 1) + chp->val = read_sample(ch); + + analog.data = &chp->val; + sr_session_send(cb_data, &packet); + } + + framep.type = SR_DF_FRAME_END; + sr_session_send(cb_data, &framep); + } devc->samples_read++; if (devc->limit_samples > 0 &&