devc->sent_samples = 0;
devc->sent_frame_samples = 0;
+ /* Setup triggers */
+ 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;
+
+ /* Disable all analog channels since using them when there are logic
+ * triggers set up would require having pre-trigger sample buffers
+ * for analog sample data.
+ */
+ for (l = sdi->channels; l; l = l->next) {
+ ch = l->data;
+ if (ch->type == SR_CHANNEL_ANALOG)
+ ch->enabled = FALSE;
+ }
+ }
+ devc->trigger_fired = FALSE;
+
/*
* Determine the numbers of logic and analog channels that are
* involved in the acquisition. Determine an offset and a mask to
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;
}
break;
case PATTERN_WALKING_ONE:
/* j contains the value of the highest bit */
- j = 1 << (devc->num_logic_channels - 1);
+ j = 1 << (devc->num_logic_channels - 1);
for (i = 0; i < size; i++) {
devc->logic_data[i] = devc->step;
if (devc->step == 0)
case PATTERN_WALKING_ZERO:
/* Same as walking one, only with inverted output */
/* j contains the value of the highest bit */
- j = 1 << (devc->num_logic_channels - 1);
+ j = 1 << (devc->num_logic_channels - 1);
for (i = 0; i < size; i++) {
devc->logic_data[i] = ~devc->step;
if (devc->step == 0)
ag_pattern_pos + i)) / 2;
ag->num_avgs++;
/* Time to send averaged data? */
- if (devc->avg_samples > 0 &&
- ag->num_avgs >= devc->avg_samples)
+ if ((devc->avg_samples > 0) && (ag->num_avgs >= devc->avg_samples))
goto do_send;
}
logic_done = devc->num_logic_channels > 0 ? 0 : samples_todo;
if (!devc->enabled_logic_channels)
logic_done = samples_todo;
+
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);
- /* Trigger */
- if (!devc->trigger_fired) {
+ /* Check for trigger and send pre-trigger data if needed */
+ if (devc->stl && (!devc->trigger_fired)) {
trigger_offset = soft_trigger_logic_check(devc->stl,
- devc->logic_data, sending_now * devc->logic_unitsize,
+ devc->logic_data, sending_now * devc->logic_unitsize,
&pre_trigger_samples);
- if (trigger_offset > -1)
+ 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;
+ /* Send logic samples if needed */
+ packet.type = SR_DF_LOGIC;
+ packet.payload = &logic;
+ logic.unitsize = devc->logic_unitsize;
+
+ if (devc->stl) {
+ if (devc->trigger_fired && (trigger_offset < (int)sending_now)) {
+ /* Send after-trigger data */
+ logic.length = (sending_now - trigger_offset) * 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;
+ /* End acquisition */
+ sr_dbg("Triggered, stopping acquisition.");
+ sr_dev_acquisition_stop(sdi);
+ break;
+ } else {
+ /* Send nothing */
+ logic_done += sending_now;
+ }
+ } else if (!devc->stl) {
+ /* No trigger defined, send logic samples */
+ logic.length = sending_now * devc->logic_unitsize;
+ logic.data = devc->logic_data;
logic_fixup_feed(devc, &logic);
sr_session_send(sdi, &packet);
- logic_done += sending_now - trigger_offset;
+ logic_done += sending_now;
}
}
/* Analog, one channel at a time */
- if (devc->trigger_fired && analog_done < samples_todo) {
+ if (analog_done < samples_todo) {
analog_sent = 0;
g_hash_table_iter_init(&iter, devc->ch_ag);
}
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;
}
uint64_t min = MIN(logic_done, analog_done);
#define LOG_PREFIX "soft-trigger"
/* @endcond */
-static size_t logic_channel_unitsize(GSList *channels)
+SR_PRIV int logic_channel_unitsize(GSList *channels)
{
- size_t number = 0;
+ int 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;
+ number++;
}
- sr_dbg("number of logic channels: %d", (int) number);
- return (number + 7) / 8;
-}
+ return (number + 7) / 8;
+}
SR_PRIV struct soft_trigger_logic *soft_trigger_logic_new(
const struct sr_dev_inst *sdi, struct sr_trigger *trigger,
stl = g_malloc0(sizeof(struct soft_trigger_logic));
stl->sdi = sdi;
stl->trigger = trigger;
- /* 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;