return i & 0x7;
}
+
+/*
+ * Return the timestamp of "DRAM cluster".
+ */
+static uint16_t sigma_dram_cluster_ts(struct sigma_dram_cluster *cluster)
+{
+ return (cluster->timestamp_hi << 8) | cluster->timestamp_lo;
+}
+
/*
* Decode chunk of 1024 bytes, 64 clusters, 7 events per cluster.
* Each event is 20ns apart, and can contain multiple samples.
* For 50 MHz and below, events contain one sample for each channel,
* spread 20 ns apart.
*/
-static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
+static int decode_chunk_ts(struct sigma_dram_line *dram_line, uint16_t *lastts,
uint16_t *lastsample, int triggerpos,
- uint16_t limit_chunk, void *cb_data)
+ uint16_t events_in_line, void *cb_data)
{
+ uint8_t *buf = (uint8_t *)dram_line;
+ struct sigma_dram_cluster *dram_cluster;
struct sr_dev_inst *sdi = cb_data;
struct dev_context *devc = sdi->priv;
uint16_t tsdiff, ts;
}
/* For each ts. */
- for (i = 0; i < 64; ++i) {
- ts = *(uint16_t *) &buf[i * 16];
+ for (i = 0; i < (events_in_line / 7); i++) {
+ dram_cluster = &dram_line->cluster[i];
+ ts = sigma_dram_cluster_ts(dram_cluster);
tsdiff = ts - *lastts;
*lastts = ts;
- /* Decode partial chunk. */
- if (limit_chunk && ts > limit_chunk)
- return SR_OK;
-
/* Pad last sample up to current point. */
numpad = tsdiff * devc->samples_per_event - clustersize;
if (numpad > 0) {
{
struct dev_context *devc = sdi->priv;
const int chunks_per_read = 32;
- unsigned char buf[chunks_per_read * CHUNK_SIZE];
- int bufsz, i, numchunks, newchunks;
-
+ struct sigma_dram_line *dram_line;
+ int bufsz;
+ uint32_t stoppos, triggerpos;
struct sr_datafeed_packet packet;
uint8_t modestatus;
+ uint32_t i;
+ uint32_t dl_lines_total, dl_lines_curr, dl_lines_done;
+ uint32_t dl_events_in_line = 64 * 7;
+ uint32_t trg_line = ~0;
+
+ dram_line = g_try_malloc0(chunks_per_read * sizeof(*dram_line));
+ if (!dram_line)
+ return FALSE;
+
sr_info("Downloading sample data.");
/* Stop acquisition. */
sigma_set_register(WRITE_MODE, 0x02, devc);
/* Get the current position. */
- sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc);
+ sigma_read_pos(&stoppos, &triggerpos, devc);
/* Check if trigger has fired. */
modestatus = sigma_get_register(READ_MODE, devc);
if (modestatus & 0x20)
- devc->state.triggerchunk = devc->state.triggerpos / 512;
- else
- devc->state.triggerchunk = -1;
-
- devc->state.chunks_downloaded = 0;
- numchunks = (devc->state.stoppos + 511) / 512;
- newchunks = MIN(chunks_per_read, numchunks - devc->state.chunks_downloaded);
-
- bufsz = sigma_read_dram(devc->state.chunks_downloaded, newchunks, buf, devc);
- /* TODO: Check bufsz. For now, just avoid compiler warnings. */
- (void)bufsz;
-
- /* Find first ts. */
- if (devc->state.chunks_downloaded == 0) {
- devc->state.lastts = RL16(buf) - 1;
- devc->state.lastsample = 0;
- }
+ trg_line = triggerpos >> 9;
- /* Decode chunks and send them to sigrok. */
- for (i = 0; i < newchunks; ++i) {
- int limit_chunk = 0;
+ /*
+ * Determine how many 1024b "DRAM lines" do we need to read from the
+ * Sigma so we have a complete set of samples. Note that the last
+ * line can be only partial, containing less than 64 clusters.
+ */
+ dl_lines_total = (stoppos >> 9) + 1;
+
+ dl_lines_done = 0;
- /* The last chunk may potentially be only in part. */
- if (devc->state.chunks_downloaded == numchunks - 1) {
- /* Find the last valid timestamp */
- limit_chunk = devc->state.stoppos % 512 + devc->state.lastts;
+ while (dl_lines_total > dl_lines_done) {
+ /* We can download only up-to 32 DRAM lines in one go! */
+ dl_lines_curr = MIN(chunks_per_read, dl_lines_total);
+
+ bufsz = sigma_read_dram(dl_lines_done, dl_lines_curr,
+ (uint8_t *)dram_line, devc);
+ /* TODO: Check bufsz. For now, just avoid compiler warnings. */
+ (void)bufsz;
+
+ /* This is the first DRAM line, so find the initial timestamp. */
+ if (dl_lines_done == 0) {
+ devc->state.lastts =
+ sigma_dram_cluster_ts(&dram_line[0].cluster[0]);
+ devc->state.lastsample = 0;
}
- if (devc->state.chunks_downloaded + i == devc->state.triggerchunk)
- decode_chunk_ts(buf + (i * CHUNK_SIZE),
- &devc->state.lastts,
- &devc->state.lastsample,
- devc->state.triggerpos & 0x1ff,
- limit_chunk, sdi);
- else
- decode_chunk_ts(buf + (i * CHUNK_SIZE),
+ for (i = 0; i < dl_lines_curr; i++) {
+ int trigger_line = -1;
+ /* The last "DRAM line" can be only partially full. */
+ if (dl_lines_done + i == dl_lines_total - 1)
+ dl_events_in_line = stoppos & 0x1ff;
+
+ /* Test if the trigger happened on this line. */
+ if (dl_lines_done + i == trg_line)
+ trigger_line = trg_line;
+
+ decode_chunk_ts(dram_line + i,
&devc->state.lastts,
&devc->state.lastsample,
- -1, limit_chunk, sdi);
+ trigger_line,
+ dl_events_in_line, sdi);
+ }
- ++devc->state.chunks_downloaded;
+ dl_lines_done += dl_lines_curr;
}
/* All done. */
dev_acquisition_stop(sdi, sdi);
+ g_free(dram_line);
+
return TRUE;
}