]> sigrok.org Git - libsigrok.git/commitdiff
asix-sigma: eliminate magic numbers in sample memory access
authorGerhard Sittig <redacted>
Sat, 9 May 2020 18:23:23 +0000 (20:23 +0200)
committerGerhard Sittig <redacted>
Fri, 29 May 2020 05:50:18 +0000 (07:50 +0200)
Add more symbolic identifiers, and rename some of the existing names for
access to SIGMA sample memory. This eliminates magic numbers and reduces
redundancy and potential for errors during maintenance.

This commit also concentrates DRAM layout related declarations in the
header file in a single location, which previously were scattered, and
separated registers from their respective bit fields.

Extend comments on the difference of events versus sample data.

src/hardware/asix-sigma/protocol.c
src/hardware/asix-sigma/protocol.h

index c4012d78b867a1056caac594cf8dd536bf819d16..f9e54089cb5ef270f5bda887339fe53686c74c87 100644 (file)
@@ -163,6 +163,14 @@ static int sigma_read_pos(uint32_t *stoppos, uint32_t *triggerpos,
         * chunks with meta data in the upper 64 bytes. Thus when the
         * decrements takes us into this upper part of the chunk, then
         * further move backwards to the end of the chunk's data part.
+        *
+        * TODO Re-consider the above comment's validity. It's true
+        * that a 1024byte row contains 512 u16 entities, of which 64
+        * are timestamps and 448 are events with sample data. It's not
+        * true that 64bytes of metadata reside at the top of a 512byte
+        * block in a row.
+        *
+        * TODO Use ROW_MASK and CLUSTERS_PER_ROW here?
         */
        if ((--*stoppos & 0x1ff) == 0x1ff)
                *stoppos -= 64;
@@ -206,7 +214,7 @@ static int sigma_read_dram(uint16_t startchunk, size_t numchunks,
        }
        sigma_write(buf, idx, devc);
 
-       return sigma_read(data, numchunks * CHUNK_SIZE, devc);
+       return sigma_read(data, numchunks * ROW_LENGTH_BYTES, devc);
 }
 
 /* Upload trigger look-up tables to Sigma. */
@@ -859,11 +867,11 @@ static void sigma_session_send(struct sr_dev_inst *sdi,
 }
 
 /*
- * This size translates to: event count (1K events per cluster), times
- * the sample width (unitsize, 16bits per event), times the maximum
- * number of samples per event.
+ * This size translates to: number of events per row (strictly speaking
+ * 448, assuming "up to 512" does not harm here) times the sample data's
+ * unit size (16 bits), times the maximum number of samples per event (4).
  */
-#define SAMPLES_BUFFER_SIZE    (1024 * 2 * 4)
+#define SAMPLES_BUFFER_SIZE    (ROW_LENGTH_U16 * sizeof(uint16_t) * 4)
 
 static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster,
                                      unsigned int events_in_cluster,
@@ -894,6 +902,13 @@ static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster,
         * If this cluster is not adjacent to the previously received
         * cluster, then send the appropriate number of samples with the
         * previous values to the sigrok session. This "decodes RLE".
+        *
+        * TODO Improve (mostly: generalize) support for queueing data
+        * before submission to the session bus. This implementation
+        * happens to work for "up to 1024 samples" despite the "up to
+        * 512 entities of 16 bits", due to the "up to 4 sample points
+        * per event" factor. A better implementation would eliminate
+        * these magic numbers.
         */
        for (ts = 0; ts < tsdiff; ts++) {
                i = ts % 1024;
@@ -1016,7 +1031,7 @@ static int decode_chunk_ts(struct sigma_dram_line *dram_line,
        triggered = 0;
 
        /* Check if trigger is in this chunk. */
-       if (trigger_event < (64 * 7)) {
+       if (trigger_event < EVENTS_PER_ROW) {
                if (devc->cur_samplerate <= SR_MHZ(50)) {
                        trigger_event -= MIN(EVENTS_PER_CLUSTER - 1,
                                             trigger_event);
@@ -1062,7 +1077,7 @@ static int download_capture(struct sr_dev_inst *sdi)
        uint32_t trg_line, trg_event;
 
        devc = sdi->priv;
-       dl_events_in_line = 64 * 7;
+       dl_events_in_line = EVENTS_PER_ROW;
 
        sr_info("Downloading sample data.");
        devc->state.state = SIGMA_DOWNLOAD;
@@ -1109,15 +1124,13 @@ static int download_capture(struct sr_dev_inst *sdi)
         *
         * When RMR_ROUND is set, the circular buffer in DRAM has wrapped
         * around. Since the status of the very next line is uncertain in
-        * that case, we skip it and start reading from the next line. The
-        * circular buffer has 32K lines (0x8000).
+        * that case, we skip it and start reading from the next line.
         */
-       dl_lines_total = (stoppos >> 9) + 1;
+       dl_first_line = 0;
+       dl_lines_total = (stoppos >> ROW_SHIFT) + 1;
        if (modestatus & RMR_ROUND) {
                dl_first_line = dl_lines_total + 1;
-               dl_lines_total = 0x8000 - 2;
-       } else {
-               dl_first_line = 0;
+               dl_lines_total = ROW_COUNT - 2;
        }
        dram_line = g_try_malloc0(chunks_per_read * sizeof(*dram_line));
        if (!dram_line)
@@ -1128,7 +1141,7 @@ static int download_capture(struct sr_dev_inst *sdi)
                dl_lines_curr = MIN(chunks_per_read, dl_lines_total - dl_lines_done);
 
                dl_line = dl_first_line + dl_lines_done;
-               dl_line %= 0x8000;
+               dl_line %= ROW_COUNT;
                bufsz = sigma_read_dram(dl_line, dl_lines_curr,
                                        (uint8_t *)dram_line, devc);
                /* TODO: Check bufsz. For now, just avoid compiler warnings. */
index 2410b3b69e13d5b77dc6e70bb125e005be2c6e23..af4e5c103ebd29b24c208991eb5a624bfce76210 100644 (file)
@@ -126,11 +126,6 @@ enum sigma_read_register {
 #define LEDSEL0                        6
 #define LEDSEL1                        7
 
-
-#define EVENTS_PER_CLUSTER     7
-
-#define CHUNK_SIZE             1024
-
 /* WRITE_MODE register fields. */
 #define WMR_SDRAMWRITEEN       (1 << 0)
 #define WMR_SDRAMREADEN                (1 << 1)
@@ -155,8 +150,16 @@ enum sigma_read_register {
  * Layout of the sample data DRAM, which will be downloaded to the PC:
  *
  * Sigma memory is organized in 32K rows. Each row contains 64 clusters.
- * Each cluster contains a timestamp (16bit) and 7 samples (16bits each).
- * Total memory size is 32K x 64 x 8 x 2 bytes == 32 MB (256 Mbit).
+ * Each cluster contains a timestamp (16bit) and 7 events (16bits each).
+ * Events contain 16 bits of sample data (potentially taken at multiple
+ * sample points, see below).
+ *
+ * Total memory size is 32K x 64 x 8 x 2 bytes == 32 MiB (256 Mbit). The
+ * size of a memory row is 1024 bytes. Assuming x16 organization of the
+ * memory array, address specs (sample count, trigger position) are kept
+ * in 24bit entities. The upper 15 bit address the "row", the lower 9 bit
+ * refer to the "event" within the row. Because there is one timestamp for
+ * seven events each, one memory row can hold up to 64x7 == 448 events.
  *
  * Sample data is represented in 16bit quantities. The first sample in
  * the cluster corresponds to the cluster's timestamp. Each next sample
@@ -164,33 +167,35 @@ enum sigma_read_register {
  * one sample period, according to the samplerate). In the absence of
  * pin level changes, no data is provided (RLE compression). A cluster
  * is enforced for each 64K ticks of the timestamp, to reliably handle
- * rollover and determination of the next timestamp of the next cluster.
+ * rollover and determine the next timestamp of the next cluster.
  *
+ * For samplerates up to 50MHz, an event directly translates to one set
+ * of sample data at a single sample point, spanning up to 16 channels.
  * For samplerates of 100MHz, there is one 16 bit entity for each 20ns
  * period (50MHz rate). The 16 bit memory contains 2 samples of up to
  * 8 channels. Bits of multiple samples are interleaved. For samplerates
  * of 200MHz one 16bit entity contains 4 samples of up to 4 channels,
  * each 5ns apart.
- *
- * Memory addresses (sample count, trigger position) are kept in 24bit
- * entities. The upper 15 bit refer to the "row", the lower 9 bit refer
- * to the "event" within the row. Because there is one timestamp for
- * seven samples each, one memory row can hold up to 64x7 == 448 samples.
  */
 
-/* One "DRAM cluster" contains a timestamp and 7 samples, 16b total. */
-struct sigma_dram_cluster {
-       uint8_t         timestamp_lo;
-       uint8_t         timestamp_hi;
-       struct {
-               uint8_t sample_hi;
-               uint8_t sample_lo;
-       }               samples[7];
-};
+#define ROW_COUNT              32768
+#define ROW_LENGTH_BYTES       1024
+#define ROW_LENGTH_U16         (ROW_LENGTH_BYTES / sizeof(uint16_t))
+#define ROW_SHIFT              9 /* log2 of u16 count */
+#define ROW_MASK               ((1UL << ROW_SHIFT) - 1)
+#define EVENTS_PER_CLUSTER     7
+#define CLUSTERS_PER_ROW       (ROW_LENGTH_U16 / (1 + EVENTS_PER_CLUSTER))
+#define EVENTS_PER_ROW         (CLUSTERS_PER_ROW * EVENTS_PER_CLUSTER)
 
-/* One "DRAM line" contains 64 "DRAM clusters", 1024b total. */
 struct sigma_dram_line {
-       struct sigma_dram_cluster       cluster[64];
+       struct sigma_dram_cluster {
+               uint8_t timestamp_lo;
+               uint8_t timestamp_hi;
+               struct sigma_dram_event {
+                       uint8_t sample_hi;
+                       uint8_t sample_lo;
+               } samples[EVENTS_PER_CLUSTER];
+       } cluster[CLUSTERS_PER_ROW];
 };
 
 struct clockselect_50 {