]> sigrok.org Git - libsigrok.git/commitdiff
Working trigger on rising and falling edges.
authorDiego F. Asanza <redacted>
Tue, 19 Apr 2016 20:27:15 +0000 (22:27 +0200)
committerUwe Hermann <redacted>
Sat, 23 Apr 2016 15:04:18 +0000 (17:04 +0200)
src/hardware/fx2lafw/dslogic.c
src/hardware/fx2lafw/protocol.c
src/hardware/fx2lafw/protocol.h

index d3cce4d074056ec2041111f45af13db62f77c237..f912278fa23c7505462b50bb700dfd41b25eb70c 100644 (file)
@@ -155,6 +155,100 @@ SR_PRIV int dslogic_stop_acquisition(const struct sr_dev_inst *sdi)
        return SR_OK;
 }
 
+/*
+ * Get the session trigger and configure the FPGA structure
+ * accordingly.
+ */
+static int dslogic_set_trigger(const struct sr_dev_inst *sdi,
+       struct dslogic_fpga_config *cfg)
+{
+       struct sr_trigger *trigger;
+       struct sr_trigger_stage *stage;
+       struct sr_trigger_match *match;
+       struct dev_context *devc;
+       const GSList *l, *m;
+       int channelbit, i = 0;
+       uint16_t v16;
+
+       devc = sdi->priv;
+       devc->trigger_en = FALSE;
+
+       cfg->trig_mask0[0] = 0xffff;
+       cfg->trig_mask1[0] = 0xffff;
+
+       cfg->trig_value0[0] = 0;
+       cfg->trig_value1[0] = 0;
+
+       cfg->trig_edge0[0] = 0;
+       cfg->trig_edge1[0] = 0;
+
+       cfg->trig_logic0[0] = 0;
+       cfg->trig_logic1[0] = 0;
+
+       cfg->trig_count0[0] = 0;
+       cfg->trig_count1[0] = 0;
+
+       if (!(trigger = sr_session_trigger_get(sdi->session)))
+               return SR_OK;
+
+       for (l = trigger->stages; l; l = l->next) {
+               stage = l->data;
+               for (m = stage->matches; m; m = m->next) {
+                       match = m->data;
+                       if (!match->channel->enabled)
+                               /* Ignore disabled channels with a trigger. */
+                               continue;
+                       channelbit = 1 << (match->channel->index);
+                       devc->trigger_en = TRUE; /* Triggered. */
+                       /* Simple trigger support (event). */
+                       if (match->match == SR_TRIGGER_ONE) {
+                               cfg->trig_mask0[0] &= ~channelbit;
+                               cfg->trig_mask1[0] &= ~channelbit;
+                               cfg->trig_value0[0] |= channelbit;
+                               cfg->trig_value1[0] |= channelbit;
+                       } else if (match->match == SR_TRIGGER_ZERO) {
+                               cfg->trig_mask0[0] &= ~channelbit;
+                               cfg->trig_mask1[0] &= ~channelbit;
+                       } else if (match->match == SR_TRIGGER_FALLING) {
+                               cfg->trig_mask0[0] &= ~channelbit;
+                               cfg->trig_mask1[0] &= ~channelbit;
+                               cfg->trig_edge0[0] |= channelbit;
+                               cfg->trig_edge1[0] |= channelbit;
+                       } else if (match->match == SR_TRIGGER_RISING) {
+                               cfg->trig_mask0[0] &= ~channelbit;
+                               cfg->trig_mask1[0] &= ~channelbit;
+                               cfg->trig_value0[0] |= channelbit;
+                               cfg->trig_value1[0] |= channelbit;
+                               cfg->trig_edge0[0] |= channelbit;
+                               cfg->trig_edge1[0] |= channelbit;
+                       } else if (match->match == SR_TRIGGER_EDGE){
+                               cfg->trig_edge0[0] |= channelbit;
+                               cfg->trig_edge1[0] |= channelbit;
+                       }
+               }
+       }
+
+       if (devc->trigger_en) {
+               for (i = 1; i < 16; i++) {
+                       cfg->trig_mask0[i] = 0xff;
+                       cfg->trig_mask1[i] = 0xff;
+                       cfg->trig_value0[i] = 0;
+                       cfg->trig_value1[i] = 0;
+                       cfg->trig_edge0[i] = 0;
+                       cfg->trig_edge1[i] = 0;
+                       cfg->trig_count0[i] = 0;
+                       cfg->trig_count1[i] = 0;
+                       cfg->trig_logic0[i] = 2;
+                       cfg->trig_logic1[i] = 2;
+               }
+               v16 = RL16(&cfg->mode);
+               v16 |= 1 << 0;
+               WL16(&cfg->mode, v16);
+       }
+
+       return SR_OK;
+}
+
 SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
@@ -207,6 +301,8 @@ SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi)
         * 15   1 = internal test mode
         * 14   1 = external test mode
         * 13   1 = loopback test mode
+        * 12   1 = stream mode
+        * 11   1 = serial trigger
         * 8-12 unused
         * 7    1 = analog mode
         * 6    1 = samplerate 400MHz
@@ -223,14 +319,16 @@ SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi)
                v16 = 1 << 14;
        else if (devc->dslogic_mode == DS_OP_LOOPBACK_TEST)
                v16 = 1 << 13;
-       if (devc->dslogic_external_clock)
-               v16 |= 1 << 2;
+       //if (devc->dslogic_external_clock)
+       //      v16 |= 1 << 1;
+       //v16 |= 1 << 0;
        WL16(&cfg.mode, v16);
-
        v32 = ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
        WL32(&cfg.divider, v32);
        WL32(&cfg.count, devc->limit_samples);
 
+       dslogic_set_trigger(sdi, &cfg);
+
        len = sizeof(struct dslogic_fpga_config);
        ret = libusb_bulk_transfer(usb->devhdl, 2 | LIBUSB_ENDPOINT_OUT,
                        (unsigned char *)&cfg, len, &transferred, USB_TIMEOUT);
index 12fc9e2c061166405b494ad813c6c704d146d1fe..8fe7b6c1fea5713a21b6066a6be5e424f43e045a 100644 (file)
@@ -304,6 +304,7 @@ SR_PRIV struct dev_context *fx2lafw_dev_new(void)
        devc->limit_samples = 0;
        devc->capture_ratio = 0;
        devc->sample_wide = FALSE;
+       devc->trigger_en = FALSE;
        devc->stl = NULL;
 
        return devc;
@@ -440,7 +441,8 @@ SR_PRIV void LIBUSB_CALL fx2lafw_receive_transfer(struct libusb_transfer *transf
        } else {
                devc->empty_transfer_count = 0;
        }
-
+       if (devc->trigger_en)
+               devc->trigger_fired = TRUE;
        if (devc->trigger_fired) {
                if (!devc->limit_samples || devc->sent_samples < devc->limit_samples) {
                        /* Send the incoming transfer to the session bus. */
index 373770d2655365ff62880d11eca4ad955aa2a7ed..487e5db19444ed42c70f3e20d31dcea9c175f16a 100644 (file)
@@ -123,6 +123,7 @@ struct dev_context {
        gboolean dslogic;
        uint16_t dslogic_mode;
        int dslogic_external_clock;
+       gboolean trigger_en;
 };
 
 SR_PRIV int fx2lafw_command_start_acquisition(const struct sr_dev_inst *sdi);