]> sigrok.org Git - libsigrok.git/commitdiff
asix-sigma: complete and extend capture mode supervision
authorGerhard Sittig <redacted>
Sun, 31 May 2020 16:38:14 +0000 (18:38 +0200)
committerGerhard Sittig <redacted>
Sun, 31 May 2020 21:53:42 +0000 (23:53 +0200)
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.

src/hardware/asix-sigma/api.c
src/hardware/asix-sigma/protocol.c
src/hardware/asix-sigma/protocol.h

index 6469b69a2bc39cdfd7549ee725eb1d477e218d93..fd9546882ee3a336c1998be3fa4a256a00e03a43 100644 (file)
@@ -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);
index 1d0fc606707a28c31c21b2a2a0eea7b060b812e2..5755e77f821f37197dd8db438fd86a0d9de78798 100644 (file)
@@ -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;
 }
index ab5f6019a9277f05aed7f2887a5481af7443471c..574183affb60f8ac40b48e528e749ea79ad00b59 100644 (file)
@@ -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,