From: Valentin Ochs Date: Sat, 20 Jun 2020 00:04:00 +0000 (+0200) Subject: fx2lafw: Add support for frames X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=bfc34b9ab0302fa0ba98eef3ce1b35c76d378589;p=libsigrok.git fx2lafw: Add support for frames When using a number of frames that is not 1, the driver will read samples up to its limit and then wait for another trigger. This will be repeated until the configured number of frames has been finished. --- diff --git a/src/hardware/fx2lafw/api.c b/src/hardware/fx2lafw/api.c index 04efcf3f..5acb0016 100644 --- a/src/hardware/fx2lafw/api.c +++ b/src/hardware/fx2lafw/api.c @@ -125,6 +125,7 @@ static const uint32_t drvopts[] = { static const uint32_t devopts[] = { SR_CONF_CONTINUOUS, + SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET, SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET, SR_CONF_CONN | SR_CONF_GET, SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, @@ -491,6 +492,9 @@ static int config_get(uint32_t key, GVariant **data, return SR_ERR; *data = g_variant_new_printf("%d.%d", usb->bus, usb->address); break; + case SR_CONF_LIMIT_FRAMES: + *data = g_variant_new_uint64(devc->limit_frames); + break; case SR_CONF_LIMIT_SAMPLES: *data = g_variant_new_uint64(devc->limit_samples); break; @@ -526,6 +530,9 @@ static int config_set(uint32_t key, GVariant *data, return SR_ERR_ARG; devc->cur_samplerate = devc->samplerates[idx]; break; + case SR_CONF_LIMIT_FRAMES: + devc->limit_frames = g_variant_get_uint64(data); + break; case SR_CONF_LIMIT_SAMPLES: devc->limit_samples = g_variant_get_uint64(data); break; diff --git a/src/hardware/fx2lafw/protocol.c b/src/hardware/fx2lafw/protocol.c index 83315808..ef41f221 100644 --- a/src/hardware/fx2lafw/protocol.c +++ b/src/hardware/fx2lafw/protocol.c @@ -414,7 +414,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; @@ -435,6 +435,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: @@ -465,38 +466,66 @@ 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 @@ -621,8 +650,10 @@ static int start_transfers(const struct sr_dev_inst *sdi) 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); diff --git a/src/hardware/fx2lafw/protocol.h b/src/hardware/fx2lafw/protocol.h index 1403c8ab..3f240c59 100644 --- a/src/hardware/fx2lafw/protocol.h +++ b/src/hardware/fx2lafw/protocol.h @@ -102,6 +102,7 @@ struct dev_context { int num_samplerates; uint64_t cur_samplerate; + uint64_t limit_frames; uint64_t limit_samples; uint64_t capture_ratio; @@ -110,6 +111,7 @@ struct dev_context { gboolean sample_wide; struct soft_trigger_logic *stl; + uint64_t num_frames; unsigned int sent_samples; int submitted_transfers; int empty_transfer_count;