X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fdemo%2Fprotocol.c;h=4358d290ce1250a4d3c80b5385f7fa41515f54c9;hb=4d33f5e112d9f77ab3ae4cbdb7fea596f4f9a644;hp=470003026a1f47172bafae45ca543555d995bfe6;hpb=4a465510fb2a427089f3460da599a4dda6e4a146;p=libsigrok.git diff --git a/src/hardware/demo/protocol.c b/src/hardware/demo/protocol.c index 47000302..4358d290 100644 --- a/src/hardware/demo/protocol.c +++ b/src/hardware/demo/protocol.c @@ -245,6 +245,19 @@ SR_PRIV void demo_generate_analog_pattern(struct analog_gen *ag, uint64_t sample } } +static uint64_t encode_number_to_gray(uint64_t nr) +{ + return nr ^ (nr >> 1); +} + +static void set_logic_data(uint64_t bits, uint8_t *data, size_t len) +{ + while (len--) { + *data++ = bits & 0xff; + bits >>= 8; + } +} + static void logic_generator(struct sr_dev_inst *sdi, uint64_t size) { struct dev_context *devc; @@ -253,6 +266,7 @@ static void logic_generator(struct sr_dev_inst *sdi, uint64_t size) uint8_t *sample; const uint8_t *image_col; size_t col_count, col_height; + uint64_t gray; devc = sdi->priv; @@ -273,9 +287,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; @@ -327,6 +340,15 @@ static void logic_generator(struct sr_dev_inst *sdi, uint64_t size) devc->step %= col_count; } break; + case PATTERN_GRAYCODE: + for (i = 0; i < size; i += devc->logic_unitsize) { + devc->step++; + devc->step &= devc->all_logic_channels_mask; + gray = encode_number_to_gray(devc->step); + gray &= devc->all_logic_channels_mask; + set_logic_data(gray, &devc->logic_data[i], devc->logic_unitsize); + } + break; default: sr_err("Unknown pattern: %d.", devc->logic_pattern); break; @@ -384,7 +406,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); @@ -446,7 +467,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; } @@ -461,21 +482,32 @@ 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 (devc->limit_frames) { + /* 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); + } + /* 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. */ todo_us = samples_todo * G_USEC_PER_SEC / devc->cur_samplerate; - logic_done = devc->num_logic_channels > 0 ? 0 : samples_todo; + 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; @@ -507,10 +539,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 @@ -521,8 +551,19 @@ 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 (devc->limit_frames && devc->sent_frame_samples >= SAMPLES_PER_FRAME) { + std_session_send_frame_end(sdi); + devc->sent_frame_samples = 0; + devc->limit_frames--; + if (!devc->limit_frames) { + sr_dbg("Requested number of frames reached."); + sr_dev_acquisition_stop(sdi); + } + } + if ((devc->limit_samples > 0 && devc->sent_samples >= devc->limit_samples) || (limit_us > 0 && devc->spent_us >= limit_us)) { @@ -539,7 +580,10 @@ 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 (devc->limit_frames) { + if (devc->sent_frame_samples == 0) + std_session_send_frame_begin(sdi); } return G_SOURCE_CONTINUE;