]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/demo/protocol.c
Demo: Implement multi-frame development feature
[libsigrok.git] / src / hardware / demo / protocol.c
index 9c4ada3b66fdc7bc1283476cc062123c0e43071f..37417f734f21e2164a43c9296185a2c4a4879b54 100644 (file)
@@ -273,9 +273,8 @@ static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
                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;
@@ -333,6 +332,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)
@@ -356,7 +383,6 @@ static void send_analog_packet(struct analog_gen *ag,
                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);
@@ -418,7 +444,7 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
        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;
        }
 
@@ -433,14 +459,17 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
        /* 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 (SAMPLES_PER_FRAME > 0)
+               samples_todo = SAMPLES_PER_FRAME;
+
        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);
+
        /* 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.
@@ -448,7 +477,11 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
        todo_us = samples_todo * G_USEC_PER_SEC / devc->cur_samplerate;
 
        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;
 
        while (logic_done < samples_todo || analog_done < samples_todo) {
                /* Logic */
@@ -461,6 +494,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;
                }
@@ -474,10 +508,8 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
                                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
@@ -506,7 +538,12 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
                        }
                }
                sr_dbg("Requested number of samples reached.");
-               sdi->driver->dev_acquisition_stop(sdi);
+               sr_dev_acquisition_stop(sdi);
+       } else {
+               if (SAMPLES_PER_FRAME > 0) {
+                       std_session_send_frame_end(sdi);
+                       std_session_send_frame_begin(sdi);
+               }
        }
 
        return G_SOURCE_CONTINUE;