}
}
+static uint64_t encode_number_to_gray(uint64_t nr)
+{
+ return nr ^ (nr >> 1);
+}
+
+static void set_logic_data(uint64_t bits, uint8_t *data, size_t len)
+{
+ while (len--) {
+ *data++ = bits & 0xff;
+ bits >>= 8;
+ }
+}
+
static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
{
struct dev_context *devc;
uint8_t *sample;
const uint8_t *image_col;
size_t col_count, col_height;
+ uint64_t gray;
devc = sdi->priv;
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)
devc->step %= col_count;
}
break;
+ case PATTERN_GRAYCODE:
+ for (i = 0; i < size; i += devc->logic_unitsize) {
+ devc->step++;
+ devc->step &= devc->all_logic_channels_mask;
+ gray = encode_number_to_gray(devc->step);
+ gray &= devc->all_logic_channels_mask;
+ set_logic_data(gray, &devc->logic_data[i], devc->logic_unitsize);
+ }
+ break;
default:
sr_err("Unknown pattern: %d.", devc->logic_pattern);
break;
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;
}
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;
if (samples_todo == 0)
return G_SOURCE_CONTINUE;
-#if (SAMPLES_PER_FRAME > 0) /* Avoid "comparison < 0 always false" warning. */
- /* Never send more samples than a frame can fit... */
- samples_todo = MIN(samples_todo, SAMPLES_PER_FRAME);
- /* ...or than we need to finish the current frame. */
- samples_todo = MIN(samples_todo, SAMPLES_PER_FRAME - devc->sent_frame_samples);
-#endif
+ if (devc->limit_frames) {
+ /* Never send more samples than a frame can fit... */
+ samples_todo = MIN(samples_todo, SAMPLES_PER_FRAME);
+ /* ...or than we need to finish the current frame. */
+ samples_todo = MIN(samples_todo,
+ SAMPLES_PER_FRAME - devc->sent_frame_samples);
+ }
/* Calculate the actual time covered by this run back from the sample
* count, rounded towards zero. This avoids getting stuck on a too-low
*/
todo_us = samples_todo * G_USEC_PER_SEC / devc->cur_samplerate;
- logic_done = devc->num_logic_channels > 0 ? 0 : samples_todo;
+ 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;
sending_now = MIN(samples_todo - logic_done,
LOGIC_BUFSIZE / devc->logic_unitsize);
logic_generator(sdi, sending_now * devc->logic_unitsize);
+ /* 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,
+ &pre_trigger_samples);
+ if (trigger_offset > -1) {
+ devc->trigger_fired = TRUE;
+ logic_done = pre_trigger_samples;
+ }
+ } else
+ trigger_offset = 0;
+
+ /* Send logic samples if needed */
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;
+
+ 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;
+ }
}
/* Analog, one channel at a time */
analog_done += analog_sent;
}
}
- /* 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 (SAMPLES_PER_FRAME > 0) /* Avoid "comparison >= 0 always true" warning. */
- if (devc->sent_frame_samples >= SAMPLES_PER_FRAME) {
+ if (devc->limit_frames && devc->sent_frame_samples >= SAMPLES_PER_FRAME) {
std_session_send_frame_end(sdi);
devc->sent_frame_samples = 0;
+ devc->limit_frames--;
+ if (!devc->limit_frames) {
+ sr_dbg("Requested number of frames reached.");
+ sr_dev_acquisition_stop(sdi);
+ }
}
-#endif
if ((devc->limit_samples > 0 && devc->sent_samples >= devc->limit_samples)
|| (limit_us > 0 && devc->spent_us >= limit_us)) {
}
sr_dbg("Requested number of samples reached.");
sr_dev_acquisition_stop(sdi);
- } else {
-#if (SAMPLES_PER_FRAME > 0)
+ } else if (devc->limit_frames) {
if (devc->sent_frame_samples == 0)
std_session_send_frame_begin(sdi);
-#endif
}
return G_SOURCE_CONTINUE;