X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=blobdiff_plain;f=src%2Fhardware%2Ffx2lafw%2Fprotocol.c;h=ec2b5c011b27ab94add03bfde6e211c2f76ef3f9;hp=e88bbd2fd6fa47e7dcda8e7d700993c3cd719ce5;hb=HEAD;hpb=7e463623382e1f574fde150b3fc88a65eaebb578 diff --git a/src/hardware/fx2lafw/protocol.c b/src/hardware/fx2lafw/protocol.c index e88bbd2f..8854f5a6 100644 --- a/src/hardware/fx2lafw/protocol.c +++ b/src/hardware/fx2lafw/protocol.c @@ -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;