]> sigrok.org Git - libsigrok.git/commitdiff
demo: Mask out logic data for disabled channels in datafeed packets
authorGerhard Sittig <redacted>
Tue, 20 Jun 2017 19:04:37 +0000 (21:04 +0200)
committerUwe Hermann <redacted>
Sat, 24 Jun 2017 14:33:50 +0000 (16:33 +0200)
The previous implementation used to provide datafeed packets which
contain logic data in positions that correspond to disabled channels.

Do mask out logic data of disabled channels in the memory image before
it is sent to the session's datafeed. This implementation works fine for
those situations where either all logic channels are enabled (default
configuration) or when only the upper channels get disabled (which can
be considered a typical use case).

For those configurations where enabled channels follow disabled channels
(i.e. setups with gaps in the sequence of enabled channels) behaviour
will be unexpected: Neither is the mask adjusted to contain gaps, nor
will enabled channels get mapped to result in a dense representation.
The respective code paths are marked with TODO comments.

Add a comment to discuss a non-obvious generator call for analog data in
the acquisition start routine, while we are here.

src/hardware/demo/api.c
src/hardware/demo/protocol.c
src/hardware/demo/protocol.h

index 92b59fe3a32f07751111e5135b82c408c3fc3c3d..f1a97eb4e5519f8a47f97c0e12290cf239c23b5a 100644 (file)
@@ -459,6 +459,8 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
        struct dev_context *devc;
        GSList *l;
        struct sr_channel *ch;
+       int bitpos;
+       uint8_t mask;
        GHashTableIter iter;
        void *value;
 
@@ -468,6 +470,11 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
        devc = sdi->priv;
        devc->sent_samples = 0;
 
+       /*
+        * Determine the numbers of logic and analog channels that are
+        * involved in the acquisition. Determine an offset and a mask to
+        * remove excess logic data content before datafeed submission.
+        */
        devc->enabled_logic_channels = 0;
        devc->enabled_analog_channels = 0;
        for (l = sdi->channels; l; l = l->next) {
@@ -478,12 +485,34 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
                        devc->enabled_analog_channels++;
                        continue;
                }
-               if (ch->type == SR_CHANNEL_LOGIC) {
-                       devc->enabled_logic_channels++;
+               if (ch->type != SR_CHANNEL_LOGIC)
                        continue;
-               }
+               /*
+                * TODO: Need we create a channel map here, such that the
+                * session datafeed packets will have a dense representation
+                * of the enabled channels' data? For example store channels
+                * D3 and D5 in bit positions 0 and 1 respectively, when all
+                * other channels are disabled? The current implementation
+                * generates a sparse layout, might provide data for logic
+                * channels that are disabled while it might suppress data
+                * from enabled channels at the same time.
+                */
+               devc->enabled_logic_channels++;
        }
-
+       devc->first_partial_logic_index = devc->enabled_logic_channels / 8;
+       bitpos = devc->enabled_logic_channels % 8;
+       mask = (1 << bitpos) - 1;
+       devc->first_partial_logic_mask = mask;
+       sr_dbg("DBG: %s(), num logic %zu, partial off %zu, mask 0x%02x",
+               __func__, devc->enabled_logic_channels,
+               devc->first_partial_logic_index,
+               devc->first_partial_logic_mask);
+
+       /*
+        * Have the waveform for analog patterns pre-generated. It's
+        * supposed to be periodic, so the generator just needs to
+        * access the prepared sample data (DDS style).
+        */
        g_hash_table_iter_init(&iter, devc->ch_ag);
        while (g_hash_table_iter_next(&iter, NULL, &value))
                demo_generate_analog_pattern(value, devc->cur_samplerate);
index 1c1ec6074617615d52671d3417970e9402104936..470003026a1f47172bafae45ca543555d995bfe6 100644 (file)
@@ -333,6 +333,34 @@ static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
        }
 }
 
+/*
+ * 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)
@@ -465,6 +493,7 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
                        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;
                }
index 79e5d886a877149964b8c27133c3c5932b968168..7930624d463ed94c4a6258455421d79fca4d33a2 100644 (file)
@@ -56,6 +56,8 @@ struct dev_context {
        uint64_t avg_samples;
        size_t enabled_logic_channels;
        size_t enabled_analog_channels;
+       size_t first_partial_logic_index;
+       uint8_t first_partial_logic_mask;
 };
 
 /* Logic patterns we can generate. */