]> sigrok.org Git - libsigrok.git/blobdiff - hardware/fx2lafw/protocol.c
fx2lafw: Don't send more samples than requested.
[libsigrok.git] / hardware / fx2lafw / protocol.c
index 62be7f6d36e08ae2cf3f28bbee80a1f2e35baae3..0d16e6c11166aca69e21d1cfdb0eedd3d8646d8c 100644 (file)
@@ -87,7 +87,7 @@ static int command_get_revid_version(libusb_device_handle *devhdl,
 SR_PRIV int fx2lafw_command_start_acquisition(libusb_device_handle *devhdl,
                uint64_t samplerate, gboolean samplewide)
 {
-       struct cmd_start_acquisition cmd;
+       struct cmd_start_acquisition cmd = { 0 };
        int delay = 0, ret;
 
        /* Compute the sample rate. */
@@ -292,12 +292,12 @@ SR_PRIV int fx2lafw_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di)
        return SR_OK;
 }
 
-SR_PRIV int fx2lafw_configure_probes(const struct sr_dev_inst *sdi)
+SR_PRIV int fx2lafw_configure_channels(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
-       struct sr_probe *probe;
+       struct sr_channel *ch;
        GSList *l;
-       int probe_bit, stage, i;
+       int channel_bit, stage, i;
        char *tc;
 
        devc = sdi->priv;
@@ -307,37 +307,39 @@ SR_PRIV int fx2lafw_configure_probes(const struct sr_dev_inst *sdi)
        }
 
        stage = -1;
-       for (l = sdi->probes; l; l = l->next) {
-               probe = (struct sr_probe *)l->data;
-               if (probe->enabled == FALSE)
+       for (l = sdi->channels; l; l = l->next) {
+               ch = (struct sr_channel *)l->data;
+               if (ch->enabled == FALSE)
                        continue;
 
-               if (probe->index > 7)
+               if (ch->index > 7)
                        devc->sample_wide = TRUE;
 
-               probe_bit = 1 << (probe->index);
-               if (!(probe->trigger))
+               channel_bit = 1 << (ch->index);
+               if (!(ch->trigger))
                        continue;
 
                stage = 0;
-               for (tc = probe->trigger; *tc; tc++) {
-                       devc->trigger_mask[stage] |= probe_bit;
+               for (tc = ch->trigger; *tc; tc++) {
+                       devc->trigger_mask[stage] |= channel_bit;
                        if (*tc == '1')
-                               devc->trigger_value[stage] |= probe_bit;
+                               devc->trigger_value[stage] |= channel_bit;
                        stage++;
                        if (stage > NUM_TRIGGER_STAGES)
                                return SR_ERR;
                }
        }
 
-       if (stage == -1)
+       if (stage == -1) {
                /*
                 * We didn't configure any triggers, make sure acquisition
                 * doesn't wait for any.
                 */
-               devc->trigger_stage = TRIGGER_FIRED;
-       else
+               devc->trigger_fired = TRUE;
+       } else {
+               devc->trigger_fired = FALSE;
                devc->trigger_stage = 0;
+       }
 
        return SR_OK;
 }
@@ -364,7 +366,7 @@ SR_PRIV void fx2lafw_abort_acquisition(struct dev_context *devc)
 {
        int i;
 
-       devc->num_samples = -1;
+       devc->acq_aborted = TRUE;
 
        for (i = devc->num_transfers - 1; i >= 0; i--) {
                if (devc->transfers[i])
@@ -429,8 +431,8 @@ SR_PRIV void fx2lafw_receive_transfer(struct libusb_transfer *transfer)
        struct sr_datafeed_packet packet;
        struct sr_datafeed_logic logic;
        struct dev_context *devc;
-       int trigger_offset, i, sample_width, cur_sample_count;
-       int trigger_offset_bytes;
+       unsigned int trigger_offset, num_samples;
+       int cur_sample_count, sample_width, i;
        uint8_t *cur_buf;
        uint16_t cur_sample;
 
@@ -440,7 +442,7 @@ SR_PRIV void fx2lafw_receive_transfer(struct libusb_transfer *transfer)
         * If acquisition has already ended, just free any queued up
         * transfer that come in.
         */
-       if (devc->num_samples == -1) {
+       if (devc->acq_aborted) {
                free_transfer(transfer);
                return;
        }
@@ -484,9 +486,8 @@ SR_PRIV void fx2lafw_receive_transfer(struct libusb_transfer *transfer)
        }
 
        trigger_offset = 0;
-       if (devc->trigger_stage >= 0) {
+       if (!devc->trigger_fired) {
                for (i = 0; i < cur_sample_count; i++) {
-
                        cur_sample = devc->sample_wide ?
                                *((uint16_t *)cur_buf + i) :
                                *((uint8_t *)cur_buf + i);
@@ -500,7 +501,7 @@ SR_PRIV void fx2lafw_receive_transfer(struct libusb_transfer *transfer)
                                if (devc->trigger_stage == NUM_TRIGGER_STAGES ||
                                        devc->trigger_mask[devc->trigger_stage] == 0) {
                                        /* Match on all trigger stages, we're done. */
-                                       trigger_offset = i + 1;
+                                       trigger_offset = i;
 
                                        /*
                                         * TODO: Send pre-trigger buffer to session bus.
@@ -516,12 +517,17 @@ SR_PRIV void fx2lafw_receive_transfer(struct libusb_transfer *transfer)
                                         */
                                        packet.type = SR_DF_LOGIC;
                                        packet.payload = &logic;
-                                       logic.unitsize = sizeof(*devc->trigger_buffer);
-                                       logic.length = devc->trigger_stage * logic.unitsize;
-                                       logic.data = devc->trigger_buffer;
+                                       num_samples = cur_sample_count - trigger_offset;
+                                       if (devc->limit_samples &&
+                                                       num_samples > devc->limit_samples - devc->sent_samples)
+                                               num_samples = devc->limit_samples - devc->sent_samples;
+                                       logic.length = num_samples * sample_width;
+                                       logic.unitsize = sample_width;
+                                       logic.data = cur_buf + trigger_offset * sample_width;
                                        sr_session_send(devc->cb_data, &packet);
+                                       devc->sent_samples += num_samples;
 
-                                       devc->trigger_stage = TRIGGER_FIRED;
+                                       devc->trigger_fired = TRUE;
                                        break;
                                }
                        } else if (devc->trigger_stage > 0) {
@@ -539,30 +545,25 @@ SR_PRIV void fx2lafw_receive_transfer(struct libusb_transfer *transfer)
                                devc->trigger_stage = 0;
                        }
                }
-       }
-
-       if (devc->trigger_stage == TRIGGER_FIRED) {
+       } else if (devc->sent_samples < devc->limit_samples) {
                /* Send the incoming transfer to the session bus. */
-               trigger_offset_bytes = trigger_offset * sample_width;
                packet.type = SR_DF_LOGIC;
                packet.payload = &logic;
-               logic.length = transfer->actual_length - trigger_offset_bytes;
+               if (devc->sent_samples + cur_sample_count > devc->limit_samples)
+                       num_samples = devc->limit_samples - devc->sent_samples;
+               else
+                       num_samples = cur_sample_count;
+               logic.length = num_samples * sample_width;
                logic.unitsize = sample_width;
-               logic.data = cur_buf + trigger_offset_bytes;
+               logic.data = cur_buf;
                sr_session_send(devc->cb_data, &packet);
+               devc->sent_samples += cur_sample_count;
+       }
 
-               devc->num_samples += cur_sample_count;
-               if (devc->limit_samples &&
-                       (unsigned int)devc->num_samples > devc->limit_samples) {
-                       fx2lafw_abort_acquisition(devc);
-                       free_transfer(transfer);
-                       return;
-               }
-       } else {
-               /*
-                * TODO: Buffer pre-trigger data in capture
-                * ratio-sized buffer.
-                */
+       if (devc->limit_samples && devc->sent_samples >= devc->limit_samples) {
+               fx2lafw_abort_acquisition(devc);
+               free_transfer(transfer);
+               return;
        }
 
        resubmit_transfer(transfer);