X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fdemo%2Fprotocol.c;h=46808fd6cf5622b4cd2ad333906ab9159059ac3d;hb=70cfec9a1419741b5972f10f7bc7aea7c15b700b;hp=94ce4ff21e2d6e3b23b35de68bf0812ba708d37b;hpb=d1144645512490c64813f4ef5a5b0c305de50260;p=libsigrok.git diff --git a/src/hardware/demo/protocol.c b/src/hardware/demo/protocol.c index 94ce4ff2..46808fd6 100644 --- a/src/hardware/demo/protocol.c +++ b/src/hardware/demo/protocol.c @@ -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) @@ -343,6 +370,9 @@ static void send_analog_packet(struct analog_gen *ag, int ag_pattern_pos; unsigned int i; + if (!ag->ch || !ag->ch->enabled) + return; + devc = sdi->priv; packet.type = SR_DF_ANALOG; packet.payload = &ag->packet; @@ -353,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); @@ -415,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; } @@ -430,14 +459,24 @@ 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 (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. @@ -445,7 +484,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 */ @@ -458,6 +501,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; } @@ -471,10 +515,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 @@ -485,8 +527,16 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data) 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)) { @@ -503,7 +553,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) + if (devc->sent_frame_samples == 0) + std_session_send_frame_begin(sdi); +#endif } return G_SOURCE_CONTINUE;