From: Gerhard Sittig Date: Sun, 31 May 2020 16:38:14 +0000 (+0200) Subject: asix-sigma: complete and extend capture mode supervision X-Git-Url: http://sigrok.org/gitweb/?p=libsigrok.git;a=commitdiff_plain;h=f14e6f7e1aab7f2ccfdffe6540d162f292c00a2c asix-sigma: complete and extend capture mode supervision Parse trigger specs early when acquisition starts, timeout calculation needs to reflect on it. Either immediately start an acquisition timeout for trigger-less configurations. Or prepare a timeout which spans the post-trigger period, but only start its active period when the trigger match was detected by the device's hardware. Extend mode tracking during acquisition to handle other special cases. Terminate acquisition when the user specified sample count limit exceeds the hardware capacity, or when no limits were specified and the device's memory is exhausted. There is a slight inaccuracy in this approach, but the implementation fails on the safe side. When both user specified limits and triggers are involved, then at least the user specified time or sample count span is provided. Usually more data is sent to the session feed, and all of the requested period is covered. This is because of the software poll period and the potential to start the timeout slightly late. As well as having added some slack for hardware pipelines in the timeout calculation. --- diff --git a/src/hardware/asix-sigma/api.c b/src/hardware/asix-sigma/api.c index 6469b69a..fd954688 100644 --- a/src/hardware/asix-sigma/api.c +++ b/src/hardware/asix-sigma/api.c @@ -433,6 +433,13 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) devc = sdi->priv; + /* Convert caller's trigger spec to driver's internal format. */ + ret = sigma_convert_trigger(sdi); + if (ret != SR_OK) { + sr_err("Could not configure triggers."); + return ret; + } + /* * Setup the device's samplerate from the value which up to now * just got checked and stored. As a byproduct this can pick and @@ -455,12 +462,6 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) if (ret != SR_OK) return ret; - ret = sigma_convert_trigger(sdi); - if (ret != SR_OK) { - sr_err("Could not configure triggers."); - return ret; - } - /* Enter trigger programming mode. */ trigsel2 = TRGSEL2_RESET; ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2, trigsel2); diff --git a/src/hardware/asix-sigma/protocol.c b/src/hardware/asix-sigma/protocol.c index 1d0fc606..5755e77f 100644 --- a/src/hardware/asix-sigma/protocol.c +++ b/src/hardware/asix-sigma/protocol.c @@ -939,6 +939,7 @@ SR_PRIV int sigma_set_acquire_timeout(struct dev_context *devc) uint64_t count_msecs, acquire_msecs; sr_sw_limits_init(&devc->limit.acquire); + devc->late_trigger_timeout = FALSE; /* Get sample count limit, convert to msecs. */ ret = sr_sw_limits_config_get(&devc->limit.config, @@ -948,6 +949,10 @@ SR_PRIV int sigma_set_acquire_timeout(struct dev_context *devc) user_count = g_variant_get_uint64(data); g_variant_unref(data); count_msecs = 0; + if (devc->use_triggers) { + user_count *= 100 - devc->capture_ratio; + user_count /= 100; + } if (user_count) count_msecs = 1000 * user_count / devc->clock.samplerate + 1; @@ -958,14 +963,18 @@ SR_PRIV int sigma_set_acquire_timeout(struct dev_context *devc) return ret; user_msecs = g_variant_get_uint64(data); g_variant_unref(data); + if (devc->use_triggers) { + user_msecs *= 100 - devc->capture_ratio; + user_msecs /= 100; + } /* Get the lesser of them, with both being optional. */ - acquire_msecs = ~0ull; + acquire_msecs = ~UINT64_C(0); if (user_count && count_msecs < acquire_msecs) acquire_msecs = count_msecs; if (user_msecs && user_msecs < acquire_msecs) acquire_msecs = user_msecs; - if (acquire_msecs == ~0ull) + if (acquire_msecs == ~UINT64_C(0)) return SR_OK; /* Add some slack, and use that timeout for acquisition. */ @@ -978,7 +987,12 @@ SR_PRIV int sigma_set_acquire_timeout(struct dev_context *devc) if (ret != SR_OK) return ret; - sr_sw_limits_acquisition_start(&devc->limit.acquire); + /* Deferred or immediate (trigger-less) timeout period start. */ + if (devc->use_triggers) + devc->late_trigger_timeout = TRUE; + else + sr_sw_limits_acquisition_start(&devc->limit.acquire); + return SR_OK; } @@ -2018,10 +2032,59 @@ static int download_capture(struct sr_dev_inst *sdi) static int sigma_capture_mode(struct sr_dev_inst *sdi) { struct dev_context *devc; + int ret; + uint32_t stoppos, triggerpos; + uint8_t mode; + gboolean full, wrapped, triggered, complete; devc = sdi->priv; + + /* + * Get and interpret current acquisition status. Some of these + * thresholds are rather arbitrary. + */ + ret = sigma_read_pos(devc, &stoppos, &triggerpos, &mode); + if (ret != SR_OK) + return FALSE; + stoppos >>= ROW_SHIFT; + full = stoppos >= ROW_COUNT - 2; + wrapped = mode & RMR_ROUND; + triggered = mode & RMR_TRIGGERED; + complete = mode & RMR_POSTTRIGGERED; + + /* + * Acquisition completed in the hardware? Start or continue + * sample memory content download. + * (Can user initiated button presses result in auto stop? + * Will they "trigger", and later result in expired time limit + * of post trigger conditions?) + */ + if (complete) + return download_capture(sdi); + + /* + * Previously configured acquisition period exceeded? Start + * sample download. Start the timeout period late when triggers + * are used (unknown period from acquisition start to trigger + * match). + */ if (sr_sw_limits_check(&devc->limit.acquire)) return download_capture(sdi); + if (devc->late_trigger_timeout && triggered) { + sr_sw_limits_acquisition_start(&devc->limit.acquire); + devc->late_trigger_timeout = FALSE; + } + + /* + * No trigger specified, and sample memory exhausted? Start + * download (may otherwise keep acquiring, even for infinite + * amounts of time without a user specified time/count limit). + * This handles situations when users specify limits which + * exceed the device's capabilities. + */ + (void)full; + if (!devc->use_triggers && wrapped) + return download_capture(sdi); return TRUE; } diff --git a/src/hardware/asix-sigma/protocol.h b/src/hardware/asix-sigma/protocol.h index ab5f6019..574183af 100644 --- a/src/hardware/asix-sigma/protocol.h +++ b/src/hardware/asix-sigma/protocol.h @@ -386,6 +386,7 @@ struct dev_context { uint64_t capture_ratio; struct sigma_trigger trigger; gboolean use_triggers; + gboolean late_trigger_timeout; enum { SIGMA_UNINITIALIZED = 0, SIGMA_CONFIG,