X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fdemo%2Fprotocol.c;fp=src%2Fhardware%2Fdemo%2Fprotocol.c;h=994c955dbeb1d263f0de83c16804a27d80c174ff;hb=6fc51fb1eeddd7b024a672ef951e760b7b9f697f;hp=4358d290ce1250a4d3c80b5385f7fa41515f54c9;hpb=31f69b096f8020d817ff26800231cb549f5ce11e;p=libsigrok.git diff --git a/src/hardware/demo/protocol.c b/src/hardware/demo/protocol.c index 4358d290..994c955d 100644 --- a/src/hardware/demo/protocol.c +++ b/src/hardware/demo/protocol.c @@ -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) {