]> 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 d0a98de279a6a54f1f1305a5005b4d25c48d5c67..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)
+SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi)
 {
+       const char *name = NULL;
        uint64_t sum;
        struct sr_resource bitstream;
        struct drv_context *drvc;
+       struct dev_context *devc;
        struct sr_usb_dev_inst *usb;
        unsigned char *buf;
        ssize_t chunksize;
@@ -73,8 +51,27 @@ SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi,
        const uint8_t cmd[3] = {0, 0, 0};
 
        drvc = sdi->driver->context;
+       devc = sdi->priv;
        usb = sdi->conn;
 
+       if (!strcmp(devc->profile->model, "DSLogic")) {
+               if (devc->cur_threshold < 1.40)
+                       name = DSLOGIC_FPGA_FIRMWARE_3V3;
+               else
+                       name = DSLOGIC_FPGA_FIRMWARE_5V;
+       } else if (!strcmp(devc->profile->model, "DSLogic Pro")){
+               name = DSLOGIC_PRO_FPGA_FIRMWARE;
+       } else if (!strcmp(devc->profile->model, "DSLogic Plus")){
+               name = DSLOGIC_PLUS_FPGA_FIRMWARE;
+       } else if (!strcmp(devc->profile->model, "DSLogic Basic")){
+               name = DSLOGIC_BASIC_FPGA_FIRMWARE;
+       } else if (!strcmp(devc->profile->model, "DSCope")) {
+               name = DSCOPE_FPGA_FIRMWARE;
+       } else {
+               sr_err("Failed to select FPGA firmware.");
+               return SR_ERR;
+       }
+
        sr_dbg("Uploading FPGA firmware '%s'.", name);
 
        result = sr_resource_open(drvc->sr_ctx, &bitstream,
@@ -177,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;
@@ -185,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;
@@ -205,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;
@@ -224,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)
@@ -270,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)
@@ -325,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) {
@@ -344,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);