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.
This commit is contained in:
Valentin Ochs 2020-06-20 02:04:00 +02:00 committed by Soeren Apel
parent f5083435cb
commit bfc34b9ab0
3 changed files with 50 additions and 10 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;