From: Soeren Apel Date: Sun, 14 Oct 2018 18:45:25 +0000 (+0200) Subject: demo: Fixup soft-trigger X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=d10781808d391bb861f3ad918109148e58026e6d;p=libsigrok.git demo: Fixup soft-trigger --- diff --git a/src/hardware/demo/api.c b/src/hardware/demo/api.c index 190dc836..7d3e0887 100644 --- a/src/hardware/demo/api.c +++ b/src/hardware/demo/api.c @@ -442,6 +442,27 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) 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 @@ -502,18 +523,6 @@ 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; } diff --git a/src/hardware/demo/protocol.c b/src/hardware/demo/protocol.c index 994c955d..ce897ad9 100644 --- a/src/hardware/demo/protocol.c +++ b/src/hardware/demo/protocol.c @@ -294,7 +294,7 @@ static void logic_generator(struct sr_dev_inst *sdi, uint64_t size) 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) @@ -309,7 +309,7 @@ static void logic_generator(struct sr_dev_inst *sdi, uint64_t size) 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) @@ -419,8 +419,7 @@ static void send_analog_packet(struct analog_gen *ag, 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; } @@ -512,42 +511,62 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data) 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); @@ -558,12 +577,6 @@ 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; } uint64_t min = MIN(logic_done, analog_done); diff --git a/src/libsigrok-internal.h b/src/libsigrok-internal.h index 6a420c66..b50cd57b 100644 --- a/src/libsigrok-internal.h +++ b/src/libsigrok-internal.h @@ -1044,6 +1044,7 @@ struct soft_trigger_logic { int pre_trigger_fill; }; +SR_PRIV int logic_channel_unitsize(GSList *channels); SR_PRIV struct soft_trigger_logic *soft_trigger_logic_new( const struct sr_dev_inst *sdi, struct sr_trigger *trigger, int pre_trigger_samples); diff --git a/src/soft-trigger.c b/src/soft-trigger.c index d932c65c..245eb4ff 100644 --- a/src/soft-trigger.c +++ b/src/soft-trigger.c @@ -26,21 +26,20 @@ #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, @@ -51,7 +50,6 @@ SR_PRIV struct soft_trigger_logic *soft_trigger_logic_new( 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;