]> sigrok.org Git - libsigrok.git/commitdiff
dslogic: Fixed FPGA setting code
authorJoel Holdsworth <redacted>
Wed, 14 Jun 2017 21:21:54 +0000 (15:21 -0600)
committerUwe Hermann <redacted>
Mon, 19 Jun 2017 22:18:16 +0000 (00:18 +0200)
src/hardware/dslogic/dslogic.c
src/hardware/dslogic/dslogic.h

index adf197f3b557f3b2c6010f806b10d6c67ad80002..f1a8465b15c3f26dc34a785c4690d78c15d3ae4e 100644 (file)
@@ -174,7 +174,7 @@ SR_PRIV int dslogic_stop_acquisition(const struct sr_dev_inst *sdi)
  * Get the session trigger and configure the FPGA structure
  * accordingly.
  */
-static int dslogic_set_trigger(const struct sr_dev_inst *sdi,
+static void dslogic_set_trigger(const struct sr_dev_inst *sdi,
        struct dslogic_fpga_config *cfg)
 {
        struct sr_trigger *trigger;
@@ -182,15 +182,19 @@ static int dslogic_set_trigger(const struct sr_dev_inst *sdi,
        struct sr_trigger_match *match;
        struct dev_context *devc;
        const GSList *l, *m;
+       int num_enabled_channels = 0, num_trigger_stages = 0;
        int channelbit, i = 0;
-       uint16_t v16;
+       uint32_t trigger_point;
 
        devc = sdi->priv;
 
        cfg->ch_en = 0;
        for (l = sdi->channels; l; l = l->next) {
                const struct sr_channel *const probe = (struct sr_channel *)l->data;
-               cfg->ch_en |= probe->enabled << probe->index;
+               if (probe->enabled) {
+                       num_enabled_channels++;
+                       cfg->ch_en |= 1 << probe->index;
+               }
        }
 
        cfg->trig_mask0[0] = 0xffff;
@@ -202,16 +206,16 @@ static int dslogic_set_trigger(const struct sr_dev_inst *sdi,
        cfg->trig_edge0[0] = 0;
        cfg->trig_edge1[0] = 0;
 
-       cfg->trig_logic0[0] = 0;
-       cfg->trig_logic1[0] = 0;
+       cfg->trig_logic0[0] = 2;
+       cfg->trig_logic1[0] = 2;
 
        cfg->trig_count[0] = 0;
 
-       cfg->trig_glb = 0;
+       cfg->trig_glb = num_enabled_channels << 4;
 
        for (i = 1; i < NUM_TRIGGER_STAGES; i++) {
-               cfg->trig_mask0[i] = 0xff;
-               cfg->trig_mask1[i] = 0xff;
+               cfg->trig_mask0[i] = 0xffff;
+               cfg->trig_mask1[i] = 0xffff;
                cfg->trig_value0[i] = 0;
                cfg->trig_value1[i] = 0;
                cfg->trig_edge0[i] = 0;
@@ -221,18 +225,24 @@ static int dslogic_set_trigger(const struct sr_dev_inst *sdi,
                cfg->trig_count[i] = 0;
        }
 
-       cfg->trig_pos = (uint32_t)(devc->capture_ratio / 100.0 * devc->limit_samples);
-       sr_dbg("pos: %d", cfg->trig_pos);
-
-       sr_dbg("configuring trigger");
+       trigger_point = (devc->capture_ratio * devc->limit_samples) / 100;
+       if (trigger_point < DSLOGIC_ATOMIC_SAMPLES)
+               trigger_point = DSLOGIC_ATOMIC_SAMPLES;
+       const uint32_t mem_depth = devc->profile->mem_depth;
+       const uint32_t max_trigger_point = devc->continuous_mode ? ((mem_depth * 10) / 100) :
+               ((mem_depth * DS_MAX_TRIG_PERCENT) / 100);
+       if (trigger_point > max_trigger_point)
+               trigger_point = max_trigger_point;
+       cfg->trig_pos = trigger_point & ~(DSLOGIC_ATOMIC_SAMPLES - 1);
 
        if (!(trigger = sr_session_trigger_get(sdi->session))) {
                sr_dbg("No session trigger found");
-               return SR_OK;
+               return;
        }
 
        for (l = trigger->stages; l; l = l->next) {
                stage = l->data;
+               num_trigger_stages++;
                for (m = stage->matches; m; m = m->next) {
                        match = m->data;
                        if (!match->channel->enabled)
@@ -267,11 +277,9 @@ static int dslogic_set_trigger(const struct sr_dev_inst *sdi,
                }
        }
 
-       v16 = RL16(&cfg->mode);
-       v16 |= 1 << 0;
-       WL16(&cfg->mode, v16);
+       cfg->trig_glb |= num_trigger_stages;
 
-       return SR_OK;
+       return;
 }
 
 SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi)
@@ -347,7 +355,9 @@ SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi)
        WL16(&cfg.mode, v16);
        v32 = ceil(DS_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate);
        WL32(&cfg.divider, v32);
-       WL32(&cfg.count, devc->limit_samples);
+
+       /* Number of 16-sample units. */
+       WL32(&cfg.count, devc->limit_samples / 16);
 
        dslogic_set_trigger(sdi, &cfg);
 
index 858cdd56b2b0e47cde6544c5b9a4f8cacf97e1f7..a3546aa0261c9ae8e05d898f8ccd98a62299495e 100644 (file)
@@ -47,6 +47,7 @@
 
 #define DS_MAX_LOGIC_DEPTH             SR_MHZ(16)
 #define DS_MAX_LOGIC_SAMPLERATE                SR_MHZ(100)
+#define DS_MAX_TRIG_PERCENT            90
 
 #define DS_MODE_TRIG_EN                        (1 << 0)
 #define DS_MODE_CLK_TYPE               (1 << 1)
@@ -64,6 +65,8 @@
 #define DS_MODE_EXT_TEST               (1 << 14)
 #define DS_MODE_INT_TEST               (1 << 15)
 
+#define DSLOGIC_ATOMIC_SAMPLES         (1 << 6)
+
 enum dslogic_operation_modes {
        DS_OP_NORMAL,
        DS_OP_INTERNAL_TEST,