]> sigrok.org Git - libsigrok.git/commitdiff
kingst-la2016: rephrase creation of the acquisition configuration
authorGerhard Sittig <redacted>
Sat, 22 Jan 2022 12:29:12 +0000 (13:29 +0100)
committerGerhard Sittig <redacted>
Sun, 6 Feb 2022 17:53:53 +0000 (18:53 +0100)
Touch up the set_sample_config() routine's implementation. Separate the
calculation of parameter values from the construction of FPGA register
access instructions. Comment on seemingly redundant pre-trigger settings
which relate to each other in non-obvious ways. Consider unsupported
samplerates fatal: With a clock input of 100MHz to 500MHz and a lowest
user settable samplerate of 20kHz the 16bit divider shall never overrun.
If it does then a driver author was not aware during maintenance. Tweak
diagnostics for improved usability. Drop an unused devc member.

src/hardware/kingst-la2016/protocol.c
src/hardware/kingst-la2016/protocol.h

index 609c8aa20517e9d4741134f85cd54f41072ec229..808ac820def99219b025e3d560f44c2e065742ef 100644 (file)
@@ -592,14 +592,14 @@ static int set_sample_config(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
        double clock_divisor;
-       uint64_t total;
-       int ret;
-       uint16_t divisor;
-       uint8_t buf[2 * sizeof(uint32_t) + 48 / 8 + sizeof(uint16_t)];
+       uint16_t divider_u16;
+       uint64_t pre_trigger_samples;
+       uint64_t pre_trigger_memory;
+       uint8_t buf[REG_TRIGGER - REG_SAMPLING]; /* Width of REG_SAMPLING. */
        uint8_t *wrptr;
+       int ret;
 
        devc = sdi->priv;
-       total = LA2016_PRE_MEM_LIMIT_BASE;
 
        if (devc->cur_samplerate > devc->max_samplerate) {
                sr_err("Too high a sample rate: %" PRIu64 ".",
@@ -608,10 +608,10 @@ static int set_sample_config(const struct sr_dev_inst *sdi)
        }
 
        clock_divisor = devc->max_samplerate / (double)devc->cur_samplerate;
-       if (clock_divisor > 0xffff)
-               clock_divisor = 0xffff;
-       divisor = (uint16_t)(clock_divisor + 0.5);
-       devc->cur_samplerate = devc->max_samplerate / divisor;
+       if (clock_divisor > 65535)
+               return SR_ERR_ARG;
+       divider_u16 = (uint16_t)(clock_divisor + 0.5);
+       devc->cur_samplerate = devc->max_samplerate / divider_u16;
 
        if (devc->limit_samples > MAX_SAMPLE_DEPTH) {
                sr_err("Too high a sample depth: %" PRIu64 ".",
@@ -619,21 +619,37 @@ static int set_sample_config(const struct sr_dev_inst *sdi)
                return SR_ERR;
        }
 
-       devc->pre_trigger_size = (devc->capture_ratio * devc->limit_samples) / 100;
+       /*
+        * The acquisition configuration communicates "pre-trigger"
+        * specs in several formats. sigrok users provide a percentage
+        * (0-100%), which translates to a pre-trigger samples count
+        * (assuming that a total samples count limit was specified).
+        * The device supports hardware compression, which depends on
+        * slowly changing input data to be effective. Fast changing
+        * input data may occupy more space in sample memory than its
+        * uncompressed form would. This is why a third parameter can
+        * limit the amount of sample memory to use for pre-trigger
+        * data. Only the upper 24 bits of that memory size spec get
+        * communicated to the device (written to its FPGA register).
+        */
+       pre_trigger_samples = devc->limit_samples * devc->capture_ratio / 100;
+       pre_trigger_memory = LA2016_PRE_MEM_LIMIT_BASE;
+       pre_trigger_memory *= devc->capture_ratio;
+       pre_trigger_memory /= 100;
+       pre_trigger_memory &= 0xffffff00ul; /* Funny register layout. */
 
-       sr_dbg("Set sample config: %" PRIu64 "kHz, %" PRIu64 " samples, trigger-pos %" PRIu64 "%%.",
-               devc->cur_samplerate / 1000,
-               devc->limit_samples,
-               devc->capture_ratio);
+       sr_dbg("Set sample config: %" PRIu64 "kHz, %" PRIu64 " samples.",
+               devc->cur_samplerate / 1000, devc->limit_samples);
+       sr_dbg("Capture ratio %" PRIu64 "%%, count %" PRIu64 ", mem %" PRIu64 ".",
+               devc->capture_ratio, pre_trigger_samples, pre_trigger_memory);
 
        wrptr = buf;
        write_u32le_inc(&wrptr, devc->limit_samples);
        write_u8_inc(&wrptr, 0);
-       write_u32le_inc(&wrptr, devc->pre_trigger_size);
-       write_u32le_inc(&wrptr, ((total * devc->capture_ratio) / 100) & 0xffffff00);
-       write_u16le_inc(&wrptr, divisor);
+       write_u32le_inc(&wrptr, pre_trigger_samples);
+       write_u32le_inc(&wrptr, pre_trigger_memory);
+       write_u16le_inc(&wrptr, divider_u16);
        write_u8_inc(&wrptr, 0);
-
        ret = ctrl_out(sdi, CMD_FPGA_SPI, REG_SAMPLING, 0, buf, wrptr - buf);
        if (ret != SR_OK) {
                sr_err("Cannot setup acquisition configuration.");
index 2064b125c0a53d02f5e44697d5307edc1af69344..76a1cc9f755999649faa07cfafca69be0170bc94 100644 (file)
@@ -118,9 +118,6 @@ struct dev_context {
        uint16_t cur_channels;
        int num_channels;
 
-       /* Values derived from user specs. */
-       uint64_t pre_trigger_size;
-
        /* Internal acquisition and download state. */
        int had_triggers_configured;
        int have_trigger;