diff --git a/src/hardware/asix-sigma/api.c b/src/hardware/asix-sigma/api.c index 7345f383..0aebe695 100644 --- a/src/hardware/asix-sigma/api.c +++ b/src/hardware/asix-sigma/api.c @@ -228,7 +228,7 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd case SR_CONF_LIMIT_SAMPLES: tmp = g_variant_get_uint64(data); devc->limit_samples = tmp; - devc->limit_msec = tmp * 1000 / devc->cur_samplerate; + devc->limit_msec = sigma_limit_samples_to_msec(devc, tmp); break; case SR_CONF_CAPTURE_RATIO: tmp = g_variant_get_uint64(data); diff --git a/src/hardware/asix-sigma/protocol.c b/src/hardware/asix-sigma/protocol.c index 94d1fed6..db89d689 100644 --- a/src/hardware/asix-sigma/protocol.c +++ b/src/hardware/asix-sigma/protocol.c @@ -519,6 +519,30 @@ static int upload_firmware(struct sr_context *ctx, return SR_OK; } +/* + * Sigma doesn't support limiting the number of samples, so we have to + * translate the number and the samplerate to an elapsed time. + * + * In addition we need to ensure that the last data cluster has passed + * the hardware pipeline, and became available to the PC side. With RLE + * compression up to 327ms could pass before another cluster accumulates + * at 200kHz samplerate when input pins don't change. + */ +SR_PRIV uint64_t sigma_limit_samples_to_msec(const struct dev_context *devc, + uint64_t limit_samples) +{ + uint64_t limit_msec; + uint64_t worst_cluster_time_ms; + + limit_msec = limit_samples * 1000 / devc->cur_samplerate; + worst_cluster_time_ms = 65536 * 1000 / devc->cur_samplerate; + /* + * One cluster time is not enough to flush pipeline when sampling + * grounded pins with 1 sample limit at 200kHz. Hence the 2* fix. + */ + return limit_msec + 2 * worst_cluster_time_ms; +} + SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi, uint64_t samplerate) { struct dev_context *devc; @@ -574,7 +598,7 @@ SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi, uint64_t sampler */ if (ret == SR_OK && devc->limit_samples) { uint64_t msecs; - msecs = devc->limit_samples * 1000 / devc->cur_samplerate; + msecs = sigma_limit_samples_to_msec(devc, devc->limit_samples); devc->limit_msec = msecs; } diff --git a/src/hardware/asix-sigma/protocol.h b/src/hardware/asix-sigma/protocol.h index 9f320858..3621f157 100644 --- a/src/hardware/asix-sigma/protocol.h +++ b/src/hardware/asix-sigma/protocol.h @@ -230,6 +230,8 @@ SR_PRIV int sigma_write_register(uint8_t reg, uint8_t *data, size_t len, SR_PRIV int sigma_set_register(uint8_t reg, uint8_t value, struct dev_context *devc); SR_PRIV int sigma_write_trigger_lut(struct triggerlut *lut, struct dev_context *devc); SR_PRIV void sigma_clear_helper(void *priv); +SR_PRIV uint64_t sigma_limit_samples_to_msec(const struct dev_context *devc, + uint64_t limit_samples); SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi, uint64_t samplerate); SR_PRIV int sigma_convert_trigger(const struct sr_dev_inst *sdi); SR_PRIV int sigma_receive_data(int fd, int revents, void *cb_data);