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 <bgolaszewski@baylibre.com>
This commit is contained in:
parent
a0648b1a12
commit
7e5a048ff2
|
@ -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,32 +599,54 @@ 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);
|
||||
for (i = 0; i < nrexpiration; i++) {
|
||||
framep.type = SR_DF_FRAME_BEGIN;
|
||||
sr_session_send(cb_data, &framep);
|
||||
|
||||
valf = read_sample(ch);
|
||||
/*
|
||||
* 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;
|
||||
|
||||
sr_session_send(cb_data, &packet);
|
||||
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);
|
||||
}
|
||||
|
||||
framep.type = SR_DF_FRAME_END;
|
||||
sr_session_send(cb_data, &framep);
|
||||
|
||||
devc->samples_read++;
|
||||
if (devc->limit_samples > 0 &&
|
||||
devc->samples_read >= devc->limit_samples) {
|
||||
|
|
Loading…
Reference in New Issue