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;
}
struct dev_context *devc;
struct drv_context *drvc;
struct version_info vi;
- int ret, i, device_count;
+ int ret = SR_ERR, i, device_count;
uint8_t revid;
char connection_id[64];
devc = sdi->priv;
usb = sdi->conn;
- if (sdi->status == SR_ST_ACTIVE)
- /* Device is already in use. */
- return SR_ERR;
-
device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
if (device_count < 0) {
sr_err("Failed to get device list: %s.",
/*
* 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;
} else {
sr_err("Failed to open device: %s.",
libusb_error_name(ret));
+ ret = SR_ERR;
break;
}
if ((ret = libusb_detach_kernel_driver(usb->devhdl, USB_INTERFACE)) < 0) {
sr_err("Failed to detach kernel driver: %s.",
libusb_error_name(ret));
- return SR_ERR;
+ ret = SR_ERR;
+ break;
}
}
}
break;
}
- sdi->status = SR_ST_ACTIVE;
sr_info("Opened device on %d.%d (logical) / %s (physical), "
"interface %d, firmware %d.%d.",
usb->bus, usb->address, connection_id,
sr_info("Detected REVID=%d, it's a Cypress CY7C68013%s.",
revid, (revid != 1) ? " (FX2)" : "A (FX2LP)");
+ ret = SR_OK;
+
break;
}
- libusb_free_device_list(devlist, 1);
- if (sdi->status != SR_ST_ACTIVE)
- return SR_ERR;
+ libusb_free_device_list(devlist, 1);
- return SR_OK;
+ return ret;
}
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;
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;
/* 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:
} 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
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);
int timeout, ret;
size_t size;
- if (sdi->status != SR_ST_ACTIVE)
- return SR_ERR_DEV_CLOSED;
-
di = sdi->driver;
drvc = di->context;
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;