]> sigrok.org Git - libsigrok.git/blobdiff - hardware/fx2lafw/protocol.c
build: Portability fixes.
[libsigrok.git] / hardware / fx2lafw / protocol.c
index 62be7f6d36e08ae2cf3f28bbee80a1f2e35baae3..433f9075c03c2d9cf804ec8d02962ebfef28e466 100644 (file)
@@ -67,9 +67,10 @@ static int command_get_fw_version(libusb_device_handle *devhdl,
        return SR_OK;
 }
 
-static int command_get_revid_version(libusb_device_handle *devhdl,
-                                    uint8_t *revid)
+static int command_get_revid_version(struct sr_dev_inst *sdi, uint8_t *revid)
 {
+       struct sr_usb_dev_inst *usb = sdi->conn;
+       libusb_device_handle *devhdl = usb->devhdl;
        int ret;
 
        ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
@@ -84,10 +85,14 @@ static int command_get_revid_version(libusb_device_handle *devhdl,
        return SR_OK;
 }
 
-SR_PRIV int fx2lafw_command_start_acquisition(libusb_device_handle *devhdl,
-               uint64_t samplerate, gboolean samplewide)
+SR_PRIV int fx2lafw_command_start_acquisition(const struct sr_dev_inst *sdi)
 {
-       struct cmd_start_acquisition cmd;
+       struct dev_context *devc = sdi->priv;
+       struct sr_usb_dev_inst *usb = sdi->conn;
+       libusb_device_handle *devhdl = usb->devhdl;
+       uint64_t samplerate = devc->cur_samplerate;
+       gboolean samplewide = devc->sample_wide;
+       struct cmd_start_acquisition cmd = { 0 };
        int delay = 0, ret;
 
        /* Compute the sample rate. */
@@ -255,7 +260,7 @@ SR_PRIV int fx2lafw_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di)
                        break;
                }
 
-               ret = command_get_revid_version(usb->devhdl, &revid);
+               ret = command_get_revid_version(sdi, &revid);
                if (ret != SR_OK) {
                        sr_err("Failed to get REVID.");
                        break;
@@ -292,56 +297,6 @@ 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)
-{
-       struct dev_context *devc;
-       struct sr_probe *probe;
-       GSList *l;
-       int probe_bit, stage, i;
-       char *tc;
-
-       devc = sdi->priv;
-       for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
-               devc->trigger_mask[i] = 0;
-               devc->trigger_value[i] = 0;
-       }
-
-       stage = -1;
-       for (l = sdi->probes; l; l = l->next) {
-               probe = (struct sr_probe *)l->data;
-               if (probe->enabled == FALSE)
-                       continue;
-
-               if (probe->index > 7)
-                       devc->sample_wide = TRUE;
-
-               probe_bit = 1 << (probe->index);
-               if (!(probe->trigger))
-                       continue;
-
-               stage = 0;
-               for (tc = probe->trigger; *tc; tc++) {
-                       devc->trigger_mask[stage] |= probe_bit;
-                       if (*tc == '1')
-                               devc->trigger_value[stage] |= probe_bit;
-                       stage++;
-                       if (stage > NUM_TRIGGER_STAGES)
-                               return SR_ERR;
-               }
-       }
-
-       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_stage = 0;
-
-       return SR_OK;
-}
-
 SR_PRIV struct dev_context *fx2lafw_dev_new(void)
 {
        struct dev_context *devc;
@@ -356,6 +311,7 @@ SR_PRIV struct dev_context *fx2lafw_dev_new(void)
        devc->cur_samplerate = 0;
        devc->limit_samples = 0;
        devc->sample_wide = FALSE;
+       devc->stl = NULL;
 
        return devc;
 }
@@ -364,7 +320,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])
@@ -372,27 +328,37 @@ SR_PRIV void fx2lafw_abort_acquisition(struct dev_context *devc)
        }
 }
 
-static void finish_acquisition(struct dev_context *devc)
+static void finish_acquisition(struct sr_dev_inst *sdi)
 {
        struct sr_datafeed_packet packet;
+       struct dev_context *devc;
+
+       devc = sdi->priv;
 
        /* Terminate session. */
        packet.type = SR_DF_END;
-       sr_session_send(devc->cb_data, &packet);
+       sr_session_send(sdi, &packet);
 
        /* Remove fds from polling. */
-       usb_source_remove(devc->ctx);
+       usb_source_remove(sdi->session, devc->ctx);
 
        devc->num_transfers = 0;
        g_free(devc->transfers);
+
+       if (devc->stl) {
+               soft_trigger_logic_free(devc->stl);
+               devc->stl = NULL;
+       }
 }
 
 static void free_transfer(struct libusb_transfer *transfer)
 {
+       struct sr_dev_inst *sdi;
        struct dev_context *devc;
        unsigned int i;
 
-       devc = transfer->user_data;
+       sdi = transfer->user_data;
+       devc = sdi->priv;
 
        g_free(transfer->buffer);
        transfer->buffer = NULL;
@@ -407,7 +373,7 @@ static void free_transfer(struct libusb_transfer *transfer)
 
        devc->submitted_transfers--;
        if (devc->submitted_transfers == 0)
-               finish_acquisition(devc);
+               finish_acquisition(sdi);
 }
 
 static void resubmit_transfer(struct libusb_transfer *transfer)
@@ -417,30 +383,29 @@ static void resubmit_transfer(struct libusb_transfer *transfer)
        if ((ret = libusb_submit_transfer(transfer)) == LIBUSB_SUCCESS)
                return;
 
+       sr_err("%s: %s", __func__, libusb_error_name(ret));
        free_transfer(transfer);
-       /* TODO: Stop session? */
 
-       sr_err("%s: %s", __func__, libusb_error_name(ret));
 }
 
 SR_PRIV void fx2lafw_receive_transfer(struct libusb_transfer *transfer)
 {
+       struct sr_dev_inst *sdi;
+       struct dev_context *devc;
        gboolean packet_has_error = FALSE;
        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;
-       uint8_t *cur_buf;
-       uint16_t cur_sample;
+       unsigned int num_samples;
+       int trigger_offset, cur_sample_count, unitsize;
 
-       devc = transfer->user_data;
+       sdi = transfer->user_data;
+       devc = sdi->priv;
 
        /*
         * 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;
        }
@@ -449,9 +414,8 @@ SR_PRIV void fx2lafw_receive_transfer(struct libusb_transfer *transfer)
                transfer->status, transfer->actual_length);
 
        /* Save incoming transfer before reusing the transfer struct. */
-       cur_buf = transfer->buffer;
-       sample_width = devc->sample_wide ? 2 : 1;
-       cur_sample_count = transfer->actual_length / sample_width;
+       unitsize = devc->sample_wide ? 2 : 1;
+       cur_sample_count = transfer->actual_length / unitsize;
 
        switch (transfer->status) {
        case LIBUSB_TRANSFER_NO_DEVICE:
@@ -483,89 +447,46 @@ SR_PRIV void fx2lafw_receive_transfer(struct libusb_transfer *transfer)
                devc->empty_transfer_count = 0;
        }
 
-       trigger_offset = 0;
-       if (devc->trigger_stage >= 0) {
-               for (i = 0; i < cur_sample_count; i++) {
-
-                       cur_sample = devc->sample_wide ?
-                               *((uint16_t *)cur_buf + i) :
-                               *((uint8_t *)cur_buf + i);
-
-                       if ((cur_sample & devc->trigger_mask[devc->trigger_stage]) ==
-                               devc->trigger_value[devc->trigger_stage]) {
-                               /* Match on this trigger stage. */
-                               devc->trigger_buffer[devc->trigger_stage] = cur_sample;
-                               devc->trigger_stage++;
-
-                               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;
-
-                                       /*
-                                        * TODO: Send pre-trigger buffer to session bus.
-                                        * Tell the frontend we hit the trigger here.
-                                        */
-                                       packet.type = SR_DF_TRIGGER;
-                                       packet.payload = NULL;
-                                       sr_session_send(devc->cb_data, &packet);
-
-                                       /*
-                                        * Send the samples that triggered it,
-                                        * since we're skipping past them.
-                                        */
-                                       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;
-                                       sr_session_send(devc->cb_data, &packet);
-
-                                       devc->trigger_stage = TRIGGER_FIRED;
-                                       break;
-                               }
-                       } else if (devc->trigger_stage > 0) {
-                               /*
-                                * We had a match before, but not in the next sample. However, we may
-                                * have a match on this stage in the next bit -- trigger on 0001 will
-                                * fail on seeing 00001, so we need to go back to stage 0 -- but at
-                                * the next sample from the one that matched originally, which the
-                                * counter increment at the end of the loop takes care of.
-                                */
-                               i -= devc->trigger_stage;
-                               if (i < -1)
-                                       i = -1; /* Oops, went back past this buffer. */
-                               /* Reset trigger stage. */
-                               devc->trigger_stage = 0;
-                       }
-               }
-       }
-
-       if (devc->trigger_stage == TRIGGER_FIRED) {
-               /* 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;
-               logic.unitsize = sample_width;
-               logic.data = cur_buf + trigger_offset_bytes;
-               sr_session_send(devc->cb_data, &packet);
-
-               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;
+       if (devc->trigger_fired) {
+               if (devc->sent_samples < devc->limit_samples) {
+                       /* Send the incoming transfer to the session bus. */
+                       packet.type = SR_DF_LOGIC;
+                       packet.payload = &logic;
+                       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 * unitsize;
+                       logic.unitsize = unitsize;
+                       logic.data = transfer->buffer;
+                       sr_session_send(devc->cb_data, &packet);
+                       devc->sent_samples += num_samples;
                }
        } else {
-               /*
-                * TODO: Buffer pre-trigger data in capture
-                * ratio-sized buffer.
-                */
+               trigger_offset = soft_trigger_logic_check(devc->stl,
+                               transfer->buffer, transfer->actual_length);
+               if (trigger_offset > -1) {
+                       packet.type = SR_DF_LOGIC;
+                       packet.payload = &logic;
+                       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 * unitsize;
+                       logic.unitsize = unitsize;
+                       logic.data = transfer->buffer + trigger_offset * unitsize;
+                       sr_session_send(devc->cb_data, &packet);
+                       devc->sent_samples += num_samples;
+
+                       devc->trigger_fired = TRUE;
+               }
        }
 
-       resubmit_transfer(transfer);
+       if (devc->limit_samples && devc->sent_samples >= devc->limit_samples) {
+               fx2lafw_abort_acquisition(devc);
+               free_transfer(transfer);
+       } else
+               resubmit_transfer(transfer);
 }
 
 static unsigned int to_bytes_per_ms(unsigned int samplerate)