]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/fx2lafw/protocol.c
output/csv: use intermediate time_t var, silence compiler warning
[libsigrok.git] / src / hardware / fx2lafw / protocol.c
index e88bbd2fd6fa47e7dcda8e7d700993c3cd719ce5..8854f5a69afd7221931b606b6d0c24a6001426c9 100644 (file)
@@ -112,7 +112,7 @@ static int command_start_acquisition(const struct sr_dev_inst *sdi)
        sr_dbg("GPIF delay = %d, clocksource = %sMHz.", delay,
                (cmd.flags & CMD_START_FLAGS_CLK_48MHZ) ? "48" : "30");
 
-       if (delay <= 0 || delay > MAX_SAMPLE_DELAY) {
+       if (delay < 0 || delay > MAX_SAMPLE_DELAY) {
                sr_err("Unable to sample at %" PRIu64 "Hz.", samplerate);
                return SR_ERR;
        }
@@ -174,7 +174,9 @@ SR_PRIV int fx2lafw_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di)
                        /*
                         * Check device by its physical USB bus/port address.
                         */
-                       usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));
+                       if (usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)) < 0)
+                               continue;
+
                        if (strcmp(sdi->connection_id, connection_id))
                                /* This is not the one. */
                                continue;
@@ -253,11 +255,14 @@ SR_PRIV struct dev_context *fx2lafw_dev_new(void)
 
        devc = g_malloc0(sizeof(struct dev_context));
        devc->profile = NULL;
+       devc->channel_names = NULL;
        devc->fw_updated = 0;
        devc->cur_samplerate = 0;
+       devc->limit_frames = 1;
        devc->limit_samples = 0;
        devc->capture_ratio = 0;
        devc->sample_wide = FALSE;
+       devc->num_frames = 0;
        devc->stl = NULL;
 
        return devc;
@@ -412,7 +417,7 @@ static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer)
        struct dev_context *devc;
        gboolean packet_has_error = FALSE;
        unsigned int num_samples;
-       int trigger_offset, cur_sample_count, unitsize;
+       int trigger_offset, cur_sample_count, unitsize, processed_samples;
        int pre_trigger_samples;
 
        sdi = transfer->user_data;
@@ -433,6 +438,7 @@ static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer)
        /* Save incoming transfer before reusing the transfer struct. */
        unitsize = devc->sample_wide ? 2 : 1;
        cur_sample_count = transfer->actual_length / unitsize;
+       processed_samples = 0;
 
        switch (transfer->status) {
        case LIBUSB_TRANSFER_NO_DEVICE:
@@ -463,38 +469,67 @@ static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer)
        } else {
                devc->empty_transfer_count = 0;
        }
+
+check_trigger:
        if (devc->trigger_fired) {
                if (!devc->limit_samples || devc->sent_samples < devc->limit_samples) {
                        /* Send the incoming transfer to the session bus. */
-                       if (devc->limit_samples && devc->sent_samples + cur_sample_count > devc->limit_samples)
+                       num_samples = cur_sample_count - processed_samples;
+                       if (devc->limit_samples && devc->sent_samples + num_samples > devc->limit_samples)
                                num_samples = devc->limit_samples - devc->sent_samples;
-                       else
-                               num_samples = cur_sample_count;
 
-                       devc->send_data_proc(sdi, (uint8_t *)transfer->buffer,
+                       devc->send_data_proc(sdi, (uint8_t *)transfer->buffer + processed_samples * unitsize,
                                num_samples * unitsize, unitsize);
                        devc->sent_samples += num_samples;
+                       processed_samples += num_samples;
                }
        } else {
                trigger_offset = soft_trigger_logic_check(devc->stl,
-                       transfer->buffer, transfer->actual_length, &pre_trigger_samples);
+                       transfer->buffer + processed_samples * unitsize,
+                       transfer->actual_length - processed_samples * unitsize,
+                       &pre_trigger_samples);
                if (trigger_offset > -1) {
+                       std_session_send_df_frame_begin(sdi);
                        devc->sent_samples += pre_trigger_samples;
-                       num_samples = cur_sample_count - trigger_offset;
+                       num_samples = cur_sample_count - processed_samples - trigger_offset;
                        if (devc->limit_samples &&
-                                       num_samples > devc->limit_samples - devc->sent_samples)
+                                       devc->sent_samples + num_samples > devc->limit_samples)
                                num_samples = devc->limit_samples - devc->sent_samples;
 
                        devc->send_data_proc(sdi, (uint8_t *)transfer->buffer
+                                       + processed_samples * unitsize
                                        + trigger_offset * unitsize,
                                        num_samples * unitsize, unitsize);
                        devc->sent_samples += num_samples;
+                       processed_samples += trigger_offset + num_samples;
 
                        devc->trigger_fired = TRUE;
                }
        }
 
-       if (devc->limit_samples && devc->sent_samples >= devc->limit_samples) {
+       const int frame_ended = devc->limit_samples && (devc->sent_samples >= devc->limit_samples);
+       const int final_frame = devc->limit_frames && (devc->num_frames >= (devc->limit_frames - 1));
+
+       if (frame_ended) {
+               devc->num_frames++;
+               devc->sent_samples = 0;
+               devc->trigger_fired = FALSE;
+               std_session_send_df_frame_end(sdi);
+
+               /* There may be another trigger in the remaining data, go back and check for it */
+               if (processed_samples < cur_sample_count) {
+                       /* Reset the trigger stage */
+                       if (devc->stl)
+                               devc->stl->cur_stage = 0;
+                       else {
+                               std_session_send_df_frame_begin(sdi);
+                               devc->trigger_fired = TRUE;
+                       }
+                       if (!final_frame)
+                               goto check_trigger;
+               }
+       }
+       if (frame_ended && final_frame) {
                fx2lafw_abort_acquisition(devc);
                free_transfer(transfer);
        } else
@@ -614,13 +649,15 @@ static int start_transfers(const struct sr_dev_inst *sdi)
        if ((trigger = sr_session_trigger_get(sdi->session))) {
                int pre_trigger_samples = 0;
                if (devc->limit_samples > 0)
-                       pre_trigger_samples = devc->capture_ratio * devc->limit_samples/100;
+                       pre_trigger_samples = (devc->capture_ratio * devc->limit_samples) / 100;
                devc->stl = soft_trigger_logic_new(sdi, trigger, pre_trigger_samples);
                if (!devc->stl)
                        return SR_ERR_MALLOC;
                devc->trigger_fired = FALSE;
-       } else
+       } else {
+               std_session_send_df_frame_begin(sdi);
                devc->trigger_fired = TRUE;
+       }
 
        num_transfers = get_number_of_transfers(devc);
 
@@ -685,6 +722,7 @@ SR_PRIV int fx2lafw_start_acquisition(const struct sr_dev_inst *sdi)
        devc = sdi->priv;
 
        devc->ctx = drvc->sr_ctx;
+       devc->num_frames = 0;
        devc->sent_samples = 0;
        devc->empty_transfer_count = 0;
        devc->acq_aborted = FALSE;