]> sigrok.org Git - libsigrok.git/blobdiff - hardware/sysclk-lwla/protocol.c
rigol-ds: Advertise SR_CONF_LIMIT_FRAMES support.
[libsigrok.git] / hardware / sysclk-lwla / protocol.c
index 5b3dd6fc504dd3281e177242a5a46b27efcae355..fb629c268a683bd2ff45e6e3c3194de3801e966c 100644 (file)
@@ -83,7 +83,9 @@ static int capture_setup(const struct sr_dev_inst *sdi)
         * 100 MHz. At the highest samplerate of 125 MHz the clock divider
         * is bypassed.
         */
-       if (devc->samplerate > 0 && devc->samplerate < SR_MHZ(100))
+       if (devc->cur_clock_source == CLOCK_SOURCE_INT
+                       && devc->samplerate > 0
+                       && devc->samplerate < SR_MHZ(100))
                divider_count = SR_MHZ(100) / devc->samplerate - 1;
        else
                divider_count = 0;
@@ -258,6 +260,10 @@ static void issue_read_start(const struct sr_dev_inst *sdi)
                devc->state = STATE_READ_PREPARE;
 }
 
+/* Issue a command as an asynchronous USB transfer which returns the device
+ * to normal state after a read operation.  Sets a new device context state
+ * on success.
+ */
 static void issue_read_end(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
@@ -341,6 +347,8 @@ static void issue_stop_capture(const struct sr_dev_inst *sdi)
  */
 static void process_capture_status(const struct sr_dev_inst *sdi)
 {
+       uint64_t duration;
+       uint64_t timescale;
        struct dev_context *devc;
        struct acquisition_state *acq;
 
@@ -358,12 +366,17 @@ static void process_capture_status(const struct sr_dev_inst *sdi)
         * in the FPGA.  These fields are definitely less than 64 bit wide
         * internally, and the unused bits occasionally even contain garbage.
         */
-       acq->mem_addr_fill    = LWLA_READ32(&acq->xfer_buf_in[0]);
-       acq->captured_samples = LWLA_READ32(&acq->xfer_buf_in[8])
-                               * (uint64_t)100000;
-       acq->capture_flags    = LWLA_READ32(&acq->xfer_buf_in[16])
+       acq->mem_addr_fill = LWLA_READ32(&acq->xfer_buf_in[0]);
+       duration           = LWLA_READ32(&acq->xfer_buf_in[8]);
+       acq->capture_flags = LWLA_READ32(&acq->xfer_buf_in[16])
                                & STATUS_FLAG_MASK;
 
+       /* The 125 MHz setting is special, and uses the same timebase
+        * for the duration field as the 100 MHz setting.
+        */
+       timescale = MIN(devc->samplerate, SR_MHZ(100));
+       acq->captured_samples = duration * timescale / 1000;
+
        sr_spew("Captured %lu words, %" PRIu64 " samples, flags 0x%02X",
                (unsigned long)acq->mem_addr_fill,
                acq->captured_samples, acq->capture_flags);
@@ -738,20 +751,22 @@ SR_PRIV int lwla_set_clock_source(const struct sr_dev_inst *sdi)
        struct dev_context *devc;
        int ret;
        enum clock_source selected;
+       size_t idx;
 
        devc = sdi->priv;
        selected = devc->selected_clock_source;
 
        if (devc->cur_clock_source != selected) {
                devc->cur_clock_source = CLOCK_SOURCE_NONE;
-
-               if (selected >= 0 && selected < G_N_ELEMENTS(bitstream_map)) {
-                       ret = lwla_send_bitstream(sdi->conn,
-                                                 bitstream_map[selected]);
-                       if (ret == SR_OK)
-                               devc->cur_clock_source = selected;
-                       return ret;
+               idx = selected;
+               if (idx >= G_N_ELEMENTS(bitstream_map)) {
+                       sr_err("Clock source (%d) out of range", selected);
+                       return SR_ERR_BUG;
                }
+               ret = lwla_send_bitstream(sdi->conn, bitstream_map[idx]);
+               if (ret == SR_OK)
+                       devc->cur_clock_source = selected;
+               return ret;
        }
        return SR_OK;
 }
@@ -764,6 +779,7 @@ SR_PRIV int lwla_setup_acquisition(const struct sr_dev_inst *sdi)
        struct sr_usb_dev_inst *usb;
        struct regval_pair regvals[7];
        int ret;
+       gboolean bypass;
 
        devc = sdi->priv;
        usb  = sdi->conn;
@@ -786,8 +802,20 @@ SR_PRIV int lwla_setup_acquisition(const struct sr_dev_inst *sdi)
        regvals[5].reg = REG_CMD_CTRL1;
        regvals[5].val = 0;
 
+       switch (devc->cur_clock_source) {
+       case CLOCK_SOURCE_INT:
+               bypass = (devc->samplerate > SR_MHZ(100));
+               break;
+       case CLOCK_SOURCE_EXT_FALL:
+       case CLOCK_SOURCE_EXT_RISE:
+               bypass = TRUE;
+               break;
+       default:
+               bypass = FALSE;
+               break;
+       }
        regvals[6].reg = REG_DIV_BYPASS;
-       regvals[6].val = (devc->samplerate > SR_MHZ(100)) ? 1 : 0;
+       regvals[6].val = bypass;
 
        ret = lwla_write_regs(usb, regvals, G_N_ELEMENTS(regvals));
        if (ret != SR_OK)