demo: Implement logic triggering.
Analog triggers and other items still need more work.
This commit is contained in:
parent
31f69b096f
commit
6fc51fb1ee
|
@ -143,6 +143,8 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
|
|||
devc->logic_pattern = DEFAULT_LOGIC_PATTERN;
|
||||
devc->num_analog_channels = num_analog_channels;
|
||||
devc->limit_frames = limit_frames;
|
||||
devc->capture_ratio = 20;
|
||||
devc->stl = NULL;
|
||||
|
||||
if (num_logic_channels > 0) {
|
||||
/* Logic channels, all in one channel group. */
|
||||
|
@ -434,6 +436,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
|||
uint8_t mask;
|
||||
GHashTableIter iter;
|
||||
void *value;
|
||||
struct sr_trigger *trigger;
|
||||
|
||||
devc = sdi->priv;
|
||||
devc->sent_samples = 0;
|
||||
|
@ -499,6 +502,18 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
|||
devc->spent_us = 0;
|
||||
devc->step = 0;
|
||||
|
||||
/* Store Triggers to stl and preset trigger_fired */
|
||||
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;
|
||||
devc->stl = soft_trigger_logic_new(sdi, trigger, pre_trigger_samples);
|
||||
if (!devc->stl)
|
||||
return SR_ERR_MALLOC;
|
||||
devc->trigger_fired = FALSE;
|
||||
} else
|
||||
devc->trigger_fired = TRUE;
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
|
@ -514,6 +529,11 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi)
|
|||
|
||||
std_session_send_df_end(sdi);
|
||||
|
||||
if (devc->stl) {
|
||||
soft_trigger_logic_free(devc->stl);
|
||||
devc->stl = NULL;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -456,6 +456,8 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
|
|||
void *value;
|
||||
uint64_t samples_todo, logic_done, analog_done, analog_sent, sending_now;
|
||||
int64_t elapsed_us, limit_us, todo_us;
|
||||
int64_t trigger_offset;
|
||||
int pre_trigger_samples;
|
||||
|
||||
(void)fd;
|
||||
(void)revents;
|
||||
|
@ -513,25 +515,39 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
|
|||
analog_done = devc->num_analog_channels > 0 ? 0 : samples_todo;
|
||||
if (!devc->enabled_analog_channels)
|
||||
analog_done = samples_todo;
|
||||
|
||||
|
||||
while (logic_done < samples_todo || analog_done < samples_todo) {
|
||||
/* Logic */
|
||||
if (logic_done < samples_todo) {
|
||||
sending_now = MIN(samples_todo - logic_done,
|
||||
LOGIC_BUFSIZE / devc->logic_unitsize);
|
||||
logic_generator(sdi, sending_now * devc->logic_unitsize);
|
||||
packet.type = SR_DF_LOGIC;
|
||||
packet.payload = &logic;
|
||||
logic.length = sending_now * devc->logic_unitsize;
|
||||
logic.unitsize = devc->logic_unitsize;
|
||||
logic.data = devc->logic_data;
|
||||
logic_fixup_feed(devc, &logic);
|
||||
sr_session_send(sdi, &packet);
|
||||
logic_done += sending_now;
|
||||
/* Trigger */
|
||||
if (!devc->trigger_fired) {
|
||||
trigger_offset = soft_trigger_logic_check(devc->stl,
|
||||
devc->logic_data, sending_now * devc->logic_unitsize,
|
||||
&pre_trigger_samples);
|
||||
if (trigger_offset > -1)
|
||||
devc->trigger_fired = TRUE;
|
||||
logic_done = pre_trigger_samples;
|
||||
} else
|
||||
trigger_offset = 0;
|
||||
|
||||
/* Remaining data */
|
||||
if (devc->trigger_fired && trigger_offset < (unsigned int)sending_now) {
|
||||
packet.type = SR_DF_LOGIC;
|
||||
packet.payload = &logic;
|
||||
logic.length = (sending_now - trigger_offset) * devc->logic_unitsize;
|
||||
logic.unitsize = devc->logic_unitsize;
|
||||
logic.data = devc->logic_data + trigger_offset * devc->logic_unitsize;
|
||||
logic_fixup_feed(devc, &logic);
|
||||
sr_session_send(sdi, &packet);
|
||||
logic_done += sending_now - trigger_offset;
|
||||
}
|
||||
}
|
||||
|
||||
/* Analog, one channel at a time */
|
||||
if (analog_done < samples_todo) {
|
||||
if (devc->trigger_fired && analog_done < samples_todo) {
|
||||
analog_sent = 0;
|
||||
|
||||
g_hash_table_iter_init(&iter, devc->ch_ag);
|
||||
|
@ -542,16 +558,17 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
|
|||
}
|
||||
analog_done += analog_sent;
|
||||
}
|
||||
|
||||
/* If trigger didn't happen continue to next iteration
|
||||
* Allow the client to stop this process
|
||||
*/
|
||||
if (!devc->trigger_fired)
|
||||
break;
|
||||
}
|
||||
/* At this point, both logic_done and analog_done should be
|
||||
* exactly equal to samples_todo, or else.
|
||||
*/
|
||||
if (logic_done != samples_todo || analog_done != samples_todo) {
|
||||
sr_err("BUG: Sample count mismatch.");
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
devc->sent_samples += samples_todo;
|
||||
devc->sent_frame_samples += samples_todo;
|
||||
|
||||
uint64_t min = MIN(logic_done, analog_done);
|
||||
devc->sent_samples += min;
|
||||
devc->sent_frame_samples += min;
|
||||
devc->spent_us += todo_us;
|
||||
|
||||
if (devc->limit_frames && devc->sent_frame_samples >= SAMPLES_PER_FRAME) {
|
||||
|
|
|
@ -119,6 +119,8 @@ struct dev_context {
|
|||
uint8_t first_partial_logic_mask;
|
||||
/* Triggers */
|
||||
uint64_t capture_ratio;
|
||||
gboolean trigger_fired;
|
||||
struct soft_trigger_logic *stl;
|
||||
};
|
||||
|
||||
static const char *analog_pattern_str[] = {
|
||||
|
|
|
@ -26,6 +26,22 @@
|
|||
#define LOG_PREFIX "soft-trigger"
|
||||
/* @endcond */
|
||||
|
||||
static size_t logic_channel_unitsize(GSList *channels)
|
||||
{
|
||||
size_t number = 0;
|
||||
struct sr_channel *channel;
|
||||
GSList *l;
|
||||
|
||||
for (l = channels; l; l = l->next) {
|
||||
channel = l->data;
|
||||
if (channel->type == SR_CHANNEL_LOGIC)
|
||||
number += 1;
|
||||
}
|
||||
sr_dbg("number of logic channels: %d", (int) number);
|
||||
return (number + 7) / 8;
|
||||
}
|
||||
|
||||
|
||||
SR_PRIV struct soft_trigger_logic *soft_trigger_logic_new(
|
||||
const struct sr_dev_inst *sdi, struct sr_trigger *trigger,
|
||||
int pre_trigger_samples)
|
||||
|
@ -35,7 +51,8 @@ SR_PRIV struct soft_trigger_logic *soft_trigger_logic_new(
|
|||
stl = g_malloc0(sizeof(struct soft_trigger_logic));
|
||||
stl->sdi = sdi;
|
||||
stl->trigger = trigger;
|
||||
stl->unitsize = (g_slist_length(sdi->channels) + 7) / 8;
|
||||
/* Retreive number of logic channels, unitsize */
|
||||
stl->unitsize = logic_channel_unitsize(sdi->channels);
|
||||
stl->prev_sample = g_malloc0(stl->unitsize);
|
||||
stl->pre_trigger_size = stl->unitsize * pre_trigger_samples;
|
||||
stl->pre_trigger_buffer = g_try_malloc(stl->pre_trigger_size);
|
||||
|
|
Loading…
Reference in New Issue