]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/dslogic/dslogic.c
fx2lafw: Moved all protocol handling to protocol.c
[libsigrok.git] / src / hardware / dslogic / dslogic.c
index 4d466143f822495adf8d934473f16e81416b8f0a..f1a8465b15c3f26dc34a785c4690d78c15d3ae4e 100644 (file)
 
 #define USB_TIMEOUT (3 * 1000)
 
-SR_PRIV int dslogic_set_vth(const struct sr_dev_inst *sdi, double vth)
-{
-       struct sr_usb_dev_inst *usb;
-       int ret;
-       const uint8_t value = (vth / 5.0) * 255;
-       const uint16_t cmd = value | (DS_ADDR_VTH << 8);
-
-       usb = sdi->conn;
-
-       /* Send the control command. */
-       ret = libusb_control_transfer(usb->devhdl,
-                       LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT,
-                       DS_CMD_WR_REG, 0x0000, 0x0000,
-                       (unsigned char *)&cmd, sizeof(cmd), 3000);
-       if (ret < 0) {
-               sr_err("Unable to send VTH command: %s.",
-               libusb_error_name(ret));
-               return SR_ERR;
-       }
-
-       return SR_OK;
-}
-
 SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi)
 {
        const char *name = NULL;
@@ -78,7 +55,7 @@ SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi)
        usb = sdi->conn;
 
        if (!strcmp(devc->profile->model, "DSLogic")) {
-               if (devc->voltage_threshold == DS_VOLTAGE_RANGE_18_33_V)
+               if (devc->cur_threshold < 1.40)
                        name = DSLOGIC_FPGA_FIRMWARE_3V3;
                else
                        name = DSLOGIC_FPGA_FIRMWARE_5V;
@@ -197,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;
@@ -205,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;
@@ -225,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;
@@ -244,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)
@@ -290,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)
@@ -345,6 +330,12 @@ SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi)
                v16 = DS_MODE_EXT_TEST;
        else if (devc->mode == DS_OP_LOOPBACK_TEST)
                v16 = DS_MODE_LPB_TEST;
+
+       if (devc->cur_samplerate == DS_MAX_LOGIC_SAMPLERATE * 2)
+               v16 |= DS_MODE_HALF_MODE;
+       else if (devc->cur_samplerate == DS_MAX_LOGIC_SAMPLERATE * 4)
+               v16 |= DS_MODE_QUAR_MODE;
+
        if (devc->continuous_mode)
                v16 |= DS_MODE_STREAM_MODE;
        if (devc->external_clock) {
@@ -364,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);