The driver internally implements the "limit samples" feature by means of
the "limit sample period" approach.  Determination of the corresponding
period of time for captures depends on the sample rate as well as the
maximum sample count, and thus needs to be re-done when either setting
changes.

Introduce a "limit_samples" variable so that the value is available when
needed later.  As a byproduct the parameter can be retrieved now (get).

Add comments to the sigma_set_samplerate() routine's sections, since
quite a bit is happening there, and interacts with other locations.

Signed-off-by: Gerhard Sittig <gerhard.sit...@gmx.net>
---
 src/hardware/asix-sigma/api.c      |  7 ++++++-
 src/hardware/asix-sigma/protocol.c | 23 +++++++++++++++++++++++
 src/hardware/asix-sigma/protocol.h |  1 +
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/hardware/asix-sigma/api.c b/src/hardware/asix-sigma/api.c
index c4e4027c8a1d..7345f3835c7a 100644
--- a/src/hardware/asix-sigma/api.c
+++ b/src/hardware/asix-sigma/api.c
@@ -42,7 +42,7 @@ static const uint32_t drvopts[] = {
 
 static const uint32_t devopts[] = {
        SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
-       SR_CONF_LIMIT_SAMPLES | SR_CONF_SET,
+       SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
        SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
        SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
        SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
@@ -102,6 +102,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList 
*options)
        devc->cur_samplerate = samplerates[0];
        devc->period_ps = 0;
        devc->limit_msec = 0;
+       devc->limit_samples = 0;
        devc->cur_firmware = -1;
        devc->num_channels = 0;
        devc->samples_per_event = 0;
@@ -185,6 +186,9 @@ static int config_get(uint32_t key, GVariant **data, const 
struct sr_dev_inst *s
        case SR_CONF_LIMIT_MSEC:
                *data = g_variant_new_uint64(devc->limit_msec);
                break;
+       case SR_CONF_LIMIT_SAMPLES:
+               *data = g_variant_new_uint64(devc->limit_samples);
+               break;
        case SR_CONF_CAPTURE_RATIO:
                *data = g_variant_new_uint64(devc->capture_ratio);
                break;
@@ -223,6 +227,7 @@ static int config_set(uint32_t key, GVariant *data, const 
struct sr_dev_inst *sd
                break;
        case SR_CONF_LIMIT_SAMPLES:
                tmp = g_variant_get_uint64(data);
+               devc->limit_samples = tmp;
                devc->limit_msec = tmp * 1000 / devc->cur_samplerate;
                break;
        case SR_CONF_CAPTURE_RATIO:
diff --git a/src/hardware/asix-sigma/protocol.c 
b/src/hardware/asix-sigma/protocol.c
index 9d621a0acd8f..0f2698fc7ab6 100644
--- a/src/hardware/asix-sigma/protocol.c
+++ b/src/hardware/asix-sigma/protocol.c
@@ -527,37 +527,60 @@ SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst 
*sdi, uint64_t sampler
        int ret;
 
        devc = sdi->priv;
        drvc = sdi->driver->context;
        ret = SR_OK;
 
+       /* Reject rates that are not in the list of supported rates. */
        for (i = 0; i < samplerates_count; i++) {
                if (samplerates[i] == samplerate)
                        break;
        }
        if (i >= samplerates_count || samplerates[i] == 0)
                return SR_ERR_SAMPLERATE;
 
+       /*
+        * Depending on the samplerates of 200/100/50- MHz, specific
+        * firmware is required and higher rates might limit the set
+        * of available channels.
+        */
        if (samplerate <= SR_MHZ(50)) {
                ret = upload_firmware(drvc->sr_ctx, 0, devc);
                devc->num_channels = 16;
        } else if (samplerate == SR_MHZ(100)) {
                ret = upload_firmware(drvc->sr_ctx, 1, devc);
                devc->num_channels = 8;
        } else if (samplerate == SR_MHZ(200)) {
                ret = upload_firmware(drvc->sr_ctx, 2, devc);
                devc->num_channels = 4;
        }
 
+       /*
+        * Derive the sample period from the sample rate as well as the
+        * number of samples that the device will communicate within
+        * an "event" (memory organization internal to the device).
+        */
        if (ret == SR_OK) {
                devc->cur_samplerate = samplerate;
                devc->period_ps = 1000000000000ULL / samplerate;
                devc->samples_per_event = 16 / devc->num_channels;
                devc->state.state = SIGMA_IDLE;
        }
 
+       /*
+        * Support for "limit_samples" is implemented by stopping
+        * acquisition after a corresponding period of time.
+        * Re-calculate that period of time, in case the limit is
+        * set first and the samplerate gets (re-)configured later.
+        */
+       if (ret == SR_OK && devc->limit_samples) {
+               uint64_t msecs;
+               msecs = devc->limit_samples * 1000 / devc->cur_samplerate;
+               devc->limit_msec = msecs;
+       }
+
        return ret;
 }
 
 /*
  * In 100 and 200 MHz mode, only a single pin rising/falling can be
  * set as trigger. In other modes, two rising/falling triggers can be set,
diff --git a/src/hardware/asix-sigma/protocol.h 
b/src/hardware/asix-sigma/protocol.h
index cbacb6715376..9f3208586c07 100644
--- a/src/hardware/asix-sigma/protocol.h
+++ b/src/hardware/asix-sigma/protocol.h
@@ -210,6 +210,7 @@ struct dev_context {
        uint64_t cur_samplerate;
        uint64_t period_ps;
        uint64_t limit_msec;
+       uint64_t limit_samples;
        struct timeval start_tv;
        int cur_firmware;
        int num_channels;
-- 
1.9.1

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
sigrok-devel mailing list
sigrok-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sigrok-devel

Reply via email to