#include <config.h>
#include "protocol.h"
-#define USB_VENDOR 0xa600
-#define USB_PRODUCT 0xa000
-#define USB_DESCRIPTION "ASIX SIGMA"
-#define USB_VENDOR_NAME "ASIX"
-#define USB_MODEL_NAME "SIGMA"
-
/*
* The ASIX Sigma supports arbitrary integer frequency divider in
* the 50MHz mode. The divider is in range 1...256 , allowing for
uint8_t buf[80];
int idx = 0;
- if ((len + 2) > sizeof(buf)) {
+ if ((2 * len + 2) > sizeof(buf)) {
sr_err("Attempted to write %zu bytes, but buffer is too small.",
- len + 2);
+ len);
return SR_ERR_BUG;
}
return SR_OK;
}
+/*
+ * Sigma doesn't support limiting the number of samples, so we have to
+ * translate the number and the samplerate to an elapsed time.
+ *
+ * In addition we need to ensure that the last data cluster has passed
+ * the hardware pipeline, and became available to the PC side. With RLE
+ * compression up to 327ms could pass before another cluster accumulates
+ * at 200kHz samplerate when input pins don't change.
+ */
+SR_PRIV uint64_t sigma_limit_samples_to_msec(const struct dev_context *devc,
+ uint64_t limit_samples)
+{
+ uint64_t limit_msec;
+ uint64_t worst_cluster_time_ms;
+
+ limit_msec = limit_samples * 1000 / devc->cur_samplerate;
+ worst_cluster_time_ms = 65536 * 1000 / devc->cur_samplerate;
+ /*
+ * One cluster time is not enough to flush pipeline when sampling
+ * grounded pins with 1 sample limit at 200kHz. Hence the 2* fix.
+ */
+ return limit_msec + 2 * worst_cluster_time_ms;
+}
+
SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi, uint64_t samplerate)
{
struct dev_context *devc;
*/
if (ret == SR_OK && devc->limit_samples) {
uint64_t msecs;
- msecs = devc->limit_samples * 1000 / devc->cur_samplerate;
+ msecs = sigma_limit_samples_to_msec(devc, devc->limit_samples);
devc->limit_msec = msecs;
}
return (cluster->timestamp_hi << 8) | cluster->timestamp_lo;
}
+/*
+ * Return one 16bit data entity of a DRAM cluster at the specified index.
+ */
+static uint16_t sigma_dram_cluster_data(struct sigma_dram_cluster *cl, int idx)
+{
+ uint16_t sample;
+
+ sample = 0;
+ sample |= cl->samples[idx].sample_lo << 0;
+ sample |= cl->samples[idx].sample_hi << 8;
+ sample = (sample >> 8) | (sample << 8);
+ return sample;
+}
+
+static void store_sr_sample(uint8_t *samples, int idx, uint16_t data)
+{
+ samples[2 * idx + 0] = (data >> 0) & 0xff;
+ samples[2 * idx + 1] = (data >> 8) & 0xff;
+}
+
static void sigma_decode_dram_cluster(struct sigma_dram_cluster *dram_cluster,
unsigned int events_in_cluster,
unsigned int triggered,
struct sigma_state *ss = &devc->state;
struct sr_datafeed_packet packet;
struct sr_datafeed_logic logic;
- uint16_t tsdiff, ts;
+ uint16_t tsdiff, ts, sample;
uint8_t samples[2048];
unsigned int i;
ts = sigma_dram_cluster_ts(dram_cluster);
tsdiff = ts - ss->lastts;
- ss->lastts = ts;
+ ss->lastts = ts + EVENTS_PER_CLUSTER;
packet.type = SR_DF_LOGIC;
packet.payload = &logic;
* sample in the cluster happens at the time of the timestamp
* and the remaining samples happen at timestamp +1...+6 .
*/
- for (ts = 0; ts < tsdiff - (EVENTS_PER_CLUSTER - 1); ts++) {
+ for (ts = 0; ts < tsdiff; ts++) {
i = ts % 1024;
- samples[2 * i + 0] = ss->lastsample & 0xff;
- samples[2 * i + 1] = ss->lastsample >> 8;
+ store_sr_sample(samples, i, ss->lastsample);
/*
* If we have 1024 samples ready or we're at the
* end of submitting the padding samples, submit
* the packet to Sigrok.
*/
- if ((i == 1023) || (ts == (tsdiff - EVENTS_PER_CLUSTER))) {
+ if ((i == 1023) || (ts == tsdiff - 1)) {
logic.length = (i + 1) * logic.unitsize;
sr_session_send(sdi, &packet);
}
* Parse the samples in current cluster and prepare them
* to be submitted to Sigrok.
*/
+ sample = 0;
for (i = 0; i < events_in_cluster; i++) {
- samples[2 * i + 1] = dram_cluster->samples[i].sample_lo;
- samples[2 * i + 0] = dram_cluster->samples[i].sample_hi;
+ sample = sigma_dram_cluster_data(dram_cluster, i);
+ store_sr_sample(samples, i, sample);
}
- /* Send data up to trigger point (if triggered). */
+ /*
+ * If a trigger position applies, then provide the datafeed with
+ * the first part of data up to that position, then send the
+ * trigger marker.
+ */
int trigger_offset = 0;
if (triggered) {
/*
}
}
+ /*
+ * Send the data after the trigger, or all of the received data
+ * if no trigger position applies.
+ */
if (events_in_cluster > 0) {
packet.type = SR_DF_LOGIC;
logic.length = events_in_cluster * logic.unitsize;
sr_session_send(sdi, &packet);
}
- ss->lastsample =
- samples[2 * (events_in_cluster - 1) + 0] |
- (samples[2 * (events_in_cluster - 1) + 1] << 8);
-
+ ss->lastsample = sample;
}
/*