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);
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;
*/
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;
}
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);