X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fasix-sigma%2Fprotocol.c;h=48de1b954ba4559d1de20f6355335212cffbb2f8;hb=e3e1f20c7f5071fb9d1912619a899e542c5d9c71;hp=ab3342a0af0812b5b3ead235b3842e0cd2f3d5ba;hpb=22f64ed88c2128ebadf09eafa3e12c8ed76cff7f;p=libsigrok.git diff --git a/src/hardware/asix-sigma/protocol.c b/src/hardware/asix-sigma/protocol.c index ab3342a0..48de1b95 100644 --- a/src/hardware/asix-sigma/protocol.c +++ b/src/hardware/asix-sigma/protocol.c @@ -590,7 +590,6 @@ SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi, uint64_t sampler */ if (ret == SR_OK) { devc->cur_samplerate = samplerate; - devc->period_ps = 1000000000000ULL / samplerate; devc->samples_per_event = 16 / devc->num_channels; devc->state.state = SIGMA_IDLE; } @@ -797,6 +796,34 @@ static void store_sr_sample(uint8_t *samples, int idx, uint16_t data) samples[2 * idx + 1] = (data >> 8) & 0xff; } +/* + * Local wrapper around sr_session_send() calls. Make sure to not send + * more samples to the session's datafeed than what was requested by a + * previously configured (optional) sample count. + */ +static void sigma_session_send(struct sr_dev_inst *sdi, + struct sr_datafeed_packet *packet) +{ + struct dev_context *devc; + struct sr_datafeed_logic *logic; + uint64_t send_now; + + devc = sdi->priv; + if (devc->limit_samples) { + logic = (void *)packet->payload; + send_now = logic->length / logic->unitsize; + if (devc->sent_samples + send_now > devc->limit_samples) { + send_now = devc->limit_samples - devc->sent_samples; + logic->length = send_now * logic->unitsize; + } + if (!send_now) + return; + devc->sent_samples += send_now; + } + + sr_session_send(sdi, packet); +} + /* * This size translates to: event count (1K events per cluster), times * the sample width (unitsize, 16bits per event), times the maximum @@ -830,15 +857,9 @@ static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster, logic.data = samples; /* - * First of all, send Sigrok a copy of the last sample from - * previous cluster as many times as needed to make up for - * the differential characteristics of data we get from the - * Sigma. Sigrok needs one sample of data per period. - * - * One DRAM cluster contains a timestamp and seven samples, - * the units of timestamp are "devc->period_ps" , the first - * sample in the cluster happens at the time of the timestamp - * and the remaining samples happen at timestamp +1...+6 . + * 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". */ for (ts = 0; ts < tsdiff; ts++) { i = ts % 1024; @@ -854,7 +875,7 @@ static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster, if ((i == 1023) || (ts == tsdiff - 1)) { logic.length = (i + 1) * logic.unitsize; for (j = 0; j < devc->samples_per_event; j++) - sr_session_send(sdi, &packet); + sigma_session_send(sdi, &packet); } } @@ -908,7 +929,7 @@ static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster, trig_count = trigger_offset * devc->samples_per_event; packet.type = SR_DF_LOGIC; logic.length = trig_count * logic.unitsize; - sr_session_send(sdi, &packet); + sigma_session_send(sdi, &packet); send_ptr += trig_count * logic.unitsize; send_count -= trig_count; } @@ -928,7 +949,7 @@ static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster, packet.type = SR_DF_LOGIC; logic.length = send_count * logic.unitsize; logic.data = send_ptr; - sr_session_send(sdi, &packet); + sigma_session_send(sdi, &packet); } ss->lastsample = sample; @@ -1004,6 +1025,7 @@ static int download_capture(struct sr_dev_inst *sdi) uint8_t modestatus; uint32_t i; uint32_t dl_lines_total, dl_lines_curr, dl_lines_done; + uint32_t dl_first_line, dl_line; uint32_t dl_events_in_line; uint32_t trg_line, trg_event; @@ -1042,20 +1064,34 @@ static int download_capture(struct sr_dev_inst *sdi) trg_event = triggerpos & 0x1ff; } + devc->sent_samples = 0; + /* - * Determine how many 1024b "DRAM lines" do we need to read from the - * Sigma so we have a complete set of samples. Note that the last - * line can be only partial, containing less than 64 clusters. + * Determine how many "DRAM lines" of 1024 bytes each we need to + * retrieve from the Sigma hardware, so that we have a complete + * set of samples. Note that the last line need not contain 64 + * clusters, it might be partially filled only. + * + * 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). */ dl_lines_total = (stoppos >> 9) + 1; - + if (modestatus & RMR_ROUND) { + dl_first_line = dl_lines_total + 1; + dl_lines_total = 0x8000 - 2; + } else { + dl_first_line = 0; + } dl_lines_done = 0; - while (dl_lines_total > dl_lines_done) { /* We can download only up-to 32 DRAM lines in one go! */ - dl_lines_curr = MIN(chunks_per_read, dl_lines_total); + dl_lines_curr = MIN(chunks_per_read, dl_lines_total - dl_lines_done); - bufsz = sigma_read_dram(dl_lines_done, dl_lines_curr, + dl_line = dl_first_line + dl_lines_done; + dl_line %= 0x8000; + bufsz = sigma_read_dram(dl_line, dl_lines_curr, (uint8_t *)dram_line, devc); /* TODO: Check bufsz. For now, just avoid compiler warnings. */ (void)bufsz; @@ -1094,34 +1130,27 @@ static int download_capture(struct sr_dev_inst *sdi) } /* - * Handle the Sigma when in CAPTURE mode. This function checks: - * - Sampling time ended - * - DRAM capacity overflow - * This function triggers download of the samples from Sigma - * in case either of the above conditions is true. + * Periodically check the Sigma status when in CAPTURE mode. This routine + * checks whether the configured sample count or sample time have passed, + * and will stop acquisition and download the acquired samples. */ static int sigma_capture_mode(struct sr_dev_inst *sdi) { struct dev_context *devc; uint64_t running_msec; - struct timeval tv; - uint32_t stoppos, triggerpos; + uint64_t current_time; devc = sdi->priv; - /* Check if the selected sampling duration passed. */ - gettimeofday(&tv, 0); - running_msec = (tv.tv_sec - devc->start_tv.tv_sec) * 1000 + - (tv.tv_usec - devc->start_tv.tv_usec) / 1000; + /* + * Check if the selected sampling duration passed. Sample count + * limits are covered by this enforced timeout as well. + */ + current_time = g_get_monotonic_time(); + running_msec = (current_time - devc->start_time) / 1000; if (running_msec >= devc->limit_msec) return download_capture(sdi); - /* Get the position in DRAM to which the FPGA is writing now. */ - sigma_read_pos(&stoppos, &triggerpos, devc); - /* Test if DRAM is full and if so, download the data. */ - if ((stoppos >> 9) == 32767) - return download_capture(sdi); - return TRUE; }