break;
case PATTERN_INC:
for (i = 0; i < size; i++) {
- for (j = 0; j < devc->logic_unitsize; j++) {
+ for (j = 0; j < devc->logic_unitsize; j++)
devc->logic_data[i + j] = devc->step;
- }
devc->step++;
}
break;
}
}
+/*
+ * Fixup a memory image of generated logic data before it gets sent to
+ * the session's datafeed. Mask out content from disabled channels.
+ *
+ * TODO: Need we apply a channel map, and enforce a dense representation
+ * of the enabled channels' data?
+ */
+static void logic_fixup_feed(struct dev_context *devc,
+ struct sr_datafeed_logic *logic)
+{
+ size_t fp_off;
+ uint8_t fp_mask;
+ size_t off, idx;
+ uint8_t *sample;
+
+ fp_off = devc->first_partial_logic_index;
+ fp_mask = devc->first_partial_logic_mask;
+ if (fp_off == logic->unitsize)
+ return;
+
+ for (off = 0; off < logic->length; off += logic->unitsize) {
+ sample = logic->data + off;
+ sample[fp_off] &= fp_mask;
+ for (idx = fp_off + 1; idx < logic->unitsize; idx++)
+ sample[idx] = 0x00;
+ }
+}
+
static void send_analog_packet(struct analog_gen *ag,
struct sr_dev_inst *sdi, uint64_t *analog_sent,
uint64_t analog_pos, uint64_t analog_todo)
ag->packet.data = ag->pattern_data + ag_pattern_pos;
ag->packet.num_samples = sending_now;
sr_session_send(sdi, &packet);
- sr_dbg("DBG: %s() sending now: %lu", __func__, (unsigned long)sending_now);
/* Whichever channel group gets there first. */
*analog_sent = MAX(*analog_sent, sending_now);
if (devc->cur_samplerate <= 0
|| (devc->num_logic_channels <= 0
&& devc->num_analog_channels <= 0)) {
- sdi->driver->dev_acquisition_stop(sdi);
+ sr_dev_acquisition_stop(sdi);
return G_SOURCE_CONTINUE;
}
/* How many samples are outstanding since the last round? */
samples_todo = (todo_us * devc->cur_samplerate + G_USEC_PER_SEC - 1)
/ G_USEC_PER_SEC;
- sr_dbg("DBG: %s() samples_todo before adjustment: %lu", __func__, (unsigned long)samples_todo);
+
if (devc->limit_samples > 0) {
if (devc->limit_samples < devc->sent_samples)
samples_todo = 0;
else if (devc->limit_samples - devc->sent_samples < samples_todo)
samples_todo = devc->limit_samples - devc->sent_samples;
}
- sr_dbg("DBG: %s() samples_todo after adjustment: %lu", __func__, (unsigned long)samples_todo);
+
+ 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
+
/* Calculate the actual time covered by this run back from the sample
* count, rounded towards zero. This avoids getting stuck on a too-low
* time delta with no samples being sent due to round-off.
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;
}
send_analog_packet(value, sdi, &analog_sent,
devc->sent_samples + analog_done,
samples_todo - analog_done);
- sr_dbg("DBG: %s() analog_sent: %lu", __func__, (unsigned long)analog_sent);
}
analog_done += analog_sent;
- sr_dbg("DBG: %s() analog_done: %lu", __func__, (unsigned long)analog_done);
}
}
/* At this point, both logic_done and analog_done should be
return G_SOURCE_REMOVE;
}
devc->sent_samples += samples_todo;
+ devc->sent_frame_samples += samples_todo;
devc->spent_us += todo_us;
+#if (SAMPLES_PER_FRAME > 0) /* Avoid "comparison >= 0 always true" warning. */
+ if (devc->sent_frame_samples >= SAMPLES_PER_FRAME) {
+ std_session_send_frame_end(sdi);
+ devc->sent_frame_samples = 0;
+ }
+#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.");
- sdi->driver->dev_acquisition_stop(sdi);
+ sr_dev_acquisition_stop(sdi);
+ } else {
+#if (SAMPLES_PER_FRAME > 0)
+ if (devc->sent_frame_samples == 0)
+ std_session_send_frame_begin(sdi);
+#endif
}
return G_SOURCE_CONTINUE;