]> sigrok.org Git - libsigrok.git/blobdiff - hardware/asix-sigma/asix-sigma.c
asix-sigma: Acquisition fixes.
[libsigrok.git] / hardware / asix-sigma / asix-sigma.c
index 70a9d7731d35e50e249c213680b29e8f822fa7ab..1c8e04bdad08f8315908e31efe38adcdb5a05286 100644 (file)
@@ -36,9 +36,8 @@
 #define USB_DESCRIPTION                        "ASIX SIGMA"
 #define USB_VENDOR_NAME                        "ASIX"
 #define USB_MODEL_NAME                 "SIGMA"
-#define USB_MODEL_VERSION              ""
 #define TRIGGER_TYPE                   "rf10"
-#define NUM_PROBES                     16
+#define NUM_CHANNELS                   16
 
 SR_PRIV struct sr_dev_driver asix_sigma_driver_info;
 static struct sr_dev_driver *di = &asix_sigma_driver_info;
@@ -58,11 +57,11 @@ static const uint64_t samplerates[] = {
 };
 
 /*
- * Probe numbers seem to go from 1-16, according to this image:
+ * Channel numbers seem to go from 1-16, according to this image:
  * http://tools.asix.net/img/sigma_sigmacab_pins_720.jpg
  * (the cable has two additional GND pins, and a TI and TO pin)
  */
-static const char *probe_names[NUM_PROBES + 1] = {
+static const char *channel_names[NUM_CHANNELS + 1] = {
        "1", "2", "3", "4", "5", "6", "7", "8",
        "9", "10", "11", "12", "13", "14", "15", "16",
        NULL,
@@ -71,8 +70,10 @@ static const char *probe_names[NUM_PROBES + 1] = {
 static const int32_t hwcaps[] = {
        SR_CONF_LOGIC_ANALYZER,
        SR_CONF_SAMPLERATE,
+       SR_CONF_TRIGGER_TYPE,
        SR_CONF_CAPTURE_RATIO,
        SR_CONF_LIMIT_MSEC,
+       SR_CONF_LIMIT_SAMPLES,
 };
 
 /* Force the FPGA to reboot. */
@@ -402,7 +403,7 @@ static int init(struct sr_context *sr_ctx)
 static GSList *scan(GSList *options)
 {
        struct sr_dev_inst *sdi;
-       struct sr_probe *probe;
+       struct sr_channel *ch;
        struct drv_context *drvc;
        struct dev_context *devc;
        GSList *devices;
@@ -450,24 +451,24 @@ static GSList *scan(GSList *options)
        devc->period_ps = 0;
        devc->limit_msec = 0;
        devc->cur_firmware = -1;
-       devc->num_probes = 0;
+       devc->num_channels = 0;
        devc->samples_per_event = 0;
        devc->capture_ratio = 50;
        devc->use_triggers = 0;
 
        /* Register SIGMA device. */
        if (!(sdi = sr_dev_inst_new(0, SR_ST_INITIALIZING, USB_VENDOR_NAME,
-                                   USB_MODEL_NAME, USB_MODEL_VERSION))) {
+                                   USB_MODEL_NAME, NULL))) {
                sr_err("%s: sdi was NULL", __func__);
                goto free;
        }
        sdi->driver = di;
 
-       for (i = 0; probe_names[i]; i++) {
-               if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
-                               probe_names[i])))
+       for (i = 0; channel_names[i]; i++) {
+               if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE,
+                               channel_names[i])))
                        return NULL;
-               sdi->probes = g_slist_append(sdi->probes, probe);
+               sdi->channels = g_slist_append(sdi->channels, ch);
        }
 
        devices = g_slist_append(devices, sdi);
@@ -624,20 +625,20 @@ static int set_samplerate(const struct sr_dev_inst *sdi, uint64_t samplerate)
 
        if (samplerate <= SR_MHZ(50)) {
                ret = upload_firmware(0, devc);
-               devc->num_probes = 16;
+               devc->num_channels = 16;
        }
        if (samplerate == SR_MHZ(100)) {
                ret = upload_firmware(1, devc);
-               devc->num_probes = 8;
+               devc->num_channels = 8;
        }
        else if (samplerate == SR_MHZ(200)) {
                ret = upload_firmware(2, devc);
-               devc->num_probes = 4;
+               devc->num_channels = 4;
        }
 
        devc->cur_samplerate = samplerate;
        devc->period_ps = 1000000000000ULL / samplerate;
-       devc->samples_per_event = 16 / devc->num_probes;
+       devc->samples_per_event = 16 / devc->num_channels;
        devc->state.state = SIGMA_IDLE;
 
        return ret;
@@ -646,26 +647,26 @@ static int set_samplerate(const struct sr_dev_inst *sdi, uint64_t samplerate)
 /*
  * In 100 and 200 MHz mode, only a single pin rising/falling can be
  * set as trigger. In other modes, two rising/falling triggers can be set,
- * in addition to value/mask trigger for any number of probes.
+ * in addition to value/mask trigger for any number of channels.
  *
  * The Sigma supports complex triggers using boolean expressions, but this
  * has not been implemented yet.
  */
-static int configure_probes(const struct sr_dev_inst *sdi)
+static int configure_channels(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc = sdi->priv;
-       const struct sr_probe *probe;
+       const struct sr_channel *ch;
        const GSList *l;
        int trigger_set = 0;
-       int probebit;
+       int channelbit;
 
        memset(&devc->trigger, 0, sizeof(struct sigma_trigger));
 
-       for (l = sdi->probes; l; l = l->next) {
-               probe = (struct sr_probe *)l->data;
-               probebit = 1 << (probe->index);
+       for (l = sdi->channels; l; l = l->next) {
+               ch = (struct sr_channel *)l->data;
+               channelbit = 1 << (ch->index);
 
-               if (!probe->enabled || !probe->trigger)
+               if (!ch->enabled || !ch->trigger)
                        continue;
 
                if (devc->cur_samplerate >= SR_MHZ(100)) {
@@ -675,10 +676,10 @@ static int configure_probes(const struct sr_dev_inst *sdi)
                                       "200MHz mode is supported.");
                                return SR_ERR;
                        }
-                       if (probe->trigger[0] == 'f')
-                               devc->trigger.fallingmask |= probebit;
-                       else if (probe->trigger[0] == 'r')
-                               devc->trigger.risingmask |= probebit;
+                       if (ch->trigger[0] == 'f')
+                               devc->trigger.fallingmask |= channelbit;
+                       else if (ch->trigger[0] == 'r')
+                               devc->trigger.risingmask |= channelbit;
                        else {
                                sr_err("Only rising/falling trigger in 100 "
                                       "and 200MHz mode is supported.");
@@ -688,20 +689,20 @@ static int configure_probes(const struct sr_dev_inst *sdi)
                        ++trigger_set;
                } else {
                        /* Simple trigger support (event). */
-                       if (probe->trigger[0] == '1') {
-                               devc->trigger.simplevalue |= probebit;
-                               devc->trigger.simplemask |= probebit;
+                       if (ch->trigger[0] == '1') {
+                               devc->trigger.simplevalue |= channelbit;
+                               devc->trigger.simplemask |= channelbit;
                        }
-                       else if (probe->trigger[0] == '0') {
-                               devc->trigger.simplevalue &= ~probebit;
-                               devc->trigger.simplemask |= probebit;
+                       else if (ch->trigger[0] == '0') {
+                               devc->trigger.simplevalue &= ~channelbit;
+                               devc->trigger.simplemask |= channelbit;
                        }
-                       else if (probe->trigger[0] == 'f') {
-                               devc->trigger.fallingmask |= probebit;
+                       else if (ch->trigger[0] == 'f') {
+                               devc->trigger.fallingmask |= channelbit;
                                ++trigger_set;
                        }
-                       else if (probe->trigger[0] == 'r') {
-                               devc->trigger.risingmask |= probebit;
+                       else if (ch->trigger[0] == 'r') {
+                               devc->trigger.risingmask |= channelbit;
                                ++trigger_set;
                        }
 
@@ -745,11 +746,11 @@ static int cleanup(void)
 }
 
 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
-               const struct sr_probe_group *probe_group)
+               const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
 
-       (void)probe_group;
+       (void)cg;
 
        switch (id) {
        case SR_CONF_SAMPLERATE:
@@ -767,33 +768,42 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
 }
 
 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
-               const struct sr_probe_group *probe_group)
+               const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
+       uint64_t num_samples;
        int ret;
 
-       (void)probe_group;
+       (void)cg;
 
        if (sdi->status != SR_ST_ACTIVE)
                return SR_ERR_DEV_CLOSED;
 
        devc = sdi->priv;
 
-       if (id == SR_CONF_SAMPLERATE) {
+       switch (id) {
+       case SR_CONF_SAMPLERATE:
                ret = set_samplerate(sdi, g_variant_get_uint64(data));
-       } else if (id == SR_CONF_LIMIT_MSEC) {
+               break;
+       case SR_CONF_LIMIT_MSEC:
                devc->limit_msec = g_variant_get_uint64(data);
                if (devc->limit_msec > 0)
                        ret = SR_OK;
                else
                        ret = SR_ERR;
-       } else if (id == SR_CONF_CAPTURE_RATIO) {
+               break;
+       case SR_CONF_LIMIT_SAMPLES:
+               num_samples = g_variant_get_uint64(data);
+               devc->limit_msec = num_samples * 1000 / devc->cur_samplerate;
+               break;
+       case SR_CONF_CAPTURE_RATIO:
                devc->capture_ratio = g_variant_get_uint64(data);
                if (devc->capture_ratio < 0 || devc->capture_ratio > 100)
                        ret = SR_ERR;
                else
                        ret = SR_OK;
-       } else {
+               break;
+       default:
                ret = SR_ERR_NA;
        }
 
@@ -801,13 +811,13 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
 }
 
 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
-               const struct sr_probe_group *probe_group)
+               const struct sr_channel_group *cg)
 {
        GVariant *gvar;
        GVariantBuilder gvb;
 
        (void)sdi;
-       (void)probe_group;
+       (void)cg;
 
        switch (key) {
        case SR_CONF_DEVICE_OPTIONS:
@@ -945,8 +955,8 @@ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
                        for (k = 0; k < devc->samples_per_event; ++k) {
                                cur_sample = 0;
 
-                               /* For each probe. */
-                               for (l = 0; l < devc->num_probes; ++l)
+                               /* For each channel. */
+                               for (l = 0; l < devc->num_channels; ++l)
                                        cur_sample |= (!!(event[j] & (1 << (l *
                                           devc->samples_per_event + k)))) << l;
 
@@ -1002,93 +1012,115 @@ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
        return SR_OK;
 }
 
-static int receive_data(int fd, int revents, void *cb_data)
+static void download_capture(struct sr_dev_inst *sdi)
 {
-       struct sr_dev_inst *sdi = cb_data;
-       struct dev_context *devc = sdi->priv;
-       struct sr_datafeed_packet packet;
+       struct dev_context *devc;
        const int chunks_per_read = 32;
        unsigned char buf[chunks_per_read * CHUNK_SIZE];
-       int bufsz, numchunks, i, newchunks;
+       int bufsz, i, numchunks, newchunks;
+
+       sr_info("Downloading sample data.");
+
+       devc = sdi->priv;
+       devc->state.chunks_downloaded = 0;
+       numchunks = (devc->state.stoppos + 511) / 512;
+       newchunks = MIN(chunks_per_read, numchunks - devc->state.chunks_downloaded);
+
+       bufsz = sigma_read_dram(devc->state.chunks_downloaded, newchunks, buf, devc);
+       /* TODO: Check bufsz. For now, just avoid compiler warnings. */
+       (void)bufsz;
+
+       /* Find first ts. */
+       if (devc->state.chunks_downloaded == 0) {
+               devc->state.lastts = RL16(buf) - 1;
+               devc->state.lastsample = 0;
+       }
+
+       /* Decode chunks and send them to sigrok. */
+       for (i = 0; i < newchunks; ++i) {
+               int limit_chunk = 0;
+
+               /* The last chunk may potentially be only in part. */
+               if (devc->state.chunks_downloaded == numchunks - 1) {
+                       /* Find the last valid timestamp */
+                       limit_chunk = devc->state.stoppos % 512 + devc->state.lastts;
+               }
+
+               if (devc->state.chunks_downloaded + i == devc->state.triggerchunk)
+                       decode_chunk_ts(buf + (i * CHUNK_SIZE),
+                                       &devc->state.lastts,
+                                       &devc->state.lastsample,
+                                       devc->state.triggerpos & 0x1ff,
+                                       limit_chunk, sdi);
+               else
+                       decode_chunk_ts(buf + (i * CHUNK_SIZE),
+                                       &devc->state.lastts,
+                                       &devc->state.lastsample,
+                                       -1, limit_chunk, sdi);
+
+               ++devc->state.chunks_downloaded;
+       }
+
+}
+
+static int receive_data(int fd, int revents, void *cb_data)
+{
+       struct sr_dev_inst *sdi;
+       struct dev_context *devc;
+       struct sr_datafeed_packet packet;
        uint64_t running_msec;
        struct timeval tv;
+       int numchunks;
+       uint8_t modestatus;
 
        (void)fd;
        (void)revents;
 
+       sdi = cb_data;
+       devc = sdi->priv;
+
        /* Get the current position. */
        sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc);
 
-       numchunks = (devc->state.stoppos + 511) / 512;
-
        if (devc->state.state == SIGMA_IDLE)
                return TRUE;
 
        if (devc->state.state == SIGMA_CAPTURE) {
+               numchunks = (devc->state.stoppos + 511) / 512;
+
                /* Check if the timer has expired, or memory is full. */
                gettimeofday(&tv, 0);
                running_msec = (tv.tv_sec - devc->start_tv.tv_sec) * 1000 +
                        (tv.tv_usec - devc->start_tv.tv_usec) / 1000;
 
                if (running_msec < devc->limit_msec && numchunks < 32767)
-                       return TRUE; /* While capturing... */
-               else
-                       dev_acquisition_stop(sdi, sdi);
-
-       }
-
-       if (devc->state.state == SIGMA_DOWNLOAD) {
-               if (devc->state.chunks_downloaded >= numchunks) {
-                       /* End of samples. */
-                       packet.type = SR_DF_END;
-                       sr_session_send(devc->cb_data, &packet);
-
-                       devc->state.state = SIGMA_IDLE;
-
+                       /* Still capturing. */
                        return TRUE;
-               }
 
-               newchunks = MIN(chunks_per_read,
-                               numchunks - devc->state.chunks_downloaded);
+               /* Stop acquisition. */
+               sigma_set_register(WRITE_MODE, 0x11, devc);
 
-               sr_info("Downloading sample data: %.0f %%.",
-                       100.0 * devc->state.chunks_downloaded / numchunks);
+               /* Set SDRAM Read Enable. */
+               sigma_set_register(WRITE_MODE, 0x02, devc);
 
-               bufsz = sigma_read_dram(devc->state.chunks_downloaded,
-                                       newchunks, buf, devc);
-               /* TODO: Check bufsz. For now, just avoid compiler warnings. */
-               (void)bufsz;
+               /* Get the current position. */
+               sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc);
 
-               /* Find first ts. */
-               if (devc->state.chunks_downloaded == 0) {
-                       devc->state.lastts = *(uint16_t *) buf - 1;
-                       devc->state.lastsample = 0;
-               }
+               /* Check if trigger has fired. */
+               modestatus = sigma_get_register(READ_MODE, devc);
+               if (modestatus & 0x20)
+                       devc->state.triggerchunk = devc->state.triggerpos / 512;
+               else
+                       devc->state.triggerchunk = -1;
 
-               /* Decode chunks and send them to sigrok. */
-               for (i = 0; i < newchunks; ++i) {
-                       int limit_chunk = 0;
+               /* Transfer captured data from device. */
+               download_capture(sdi);
 
-                       /* The last chunk may potentially be only in part. */
-                       if (devc->state.chunks_downloaded == numchunks - 1) {
-                               /* Find the last valid timestamp */
-                               limit_chunk = devc->state.stoppos % 512 + devc->state.lastts;
-                       }
+               /* All done. */
+               packet.type = SR_DF_END;
+               sr_session_send(sdi, &packet);
 
-                       if (devc->state.chunks_downloaded + i == devc->state.triggerchunk)
-                               decode_chunk_ts(buf + (i * CHUNK_SIZE),
-                                               &devc->state.lastts,
-                                               &devc->state.lastsample,
-                                               devc->state.triggerpos & 0x1ff,
-                                               limit_chunk, sdi);
-                       else
-                               decode_chunk_ts(buf + (i * CHUNK_SIZE),
-                                               &devc->state.lastts,
-                                               &devc->state.lastsample,
-                                               -1, limit_chunk, sdi);
-
-                       ++devc->state.chunks_downloaded;
-               }
+               dev_acquisition_stop(sdi, sdi);
        }
 
        return TRUE;
@@ -1099,14 +1131,14 @@ static void build_lut_entry(uint16_t value, uint16_t mask, uint16_t *entry)
 {
        int i, j, k, bit;
 
-       /* For each quad probe. */
+       /* For each quad channel. */
        for (i = 0; i < 4; ++i) {
                entry[i] = 0xffff;
 
                /* For each bit in LUT. */
                for (j = 0; j < 16; ++j)
 
-                       /* For each probe in quad. */
+                       /* For each channel in quad. */
                        for (k = 0; k < 4; ++k) {
                                bit = 1 << (i * 4 + k);
 
@@ -1265,8 +1297,8 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
 
        devc = sdi->priv;
 
-       if (configure_probes(sdi) != SR_OK) {
-               sr_err("Failed to configure probes.");
+       if (configure_channels(sdi) != SR_OK) {
+               sr_err("Failed to configure channels.");
                return SR_ERR;
        }
 
@@ -1319,10 +1351,10 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
 
        /* Set clock select register. */
        if (devc->cur_samplerate == SR_MHZ(200))
-               /* Enable 4 probes. */
+               /* Enable 4 channels. */
                sigma_set_register(WRITE_CLOCK_SELECT, 0xf0, devc);
        else if (devc->cur_samplerate == SR_MHZ(100))
-               /* Enable 8 probes. */
+               /* Enable 8 channels. */
                sigma_set_register(WRITE_CLOCK_SELECT, 0x00, devc);
        else {
                /*
@@ -1333,7 +1365,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
 
                clockselect.async = 0;
                clockselect.fraction = frac;
-               clockselect.disabled_probes = 0;
+               clockselect.disabled_channels = 0;
 
                sigma_write_register(WRITE_CLOCK_SELECT,
                                     (uint8_t *) &clockselect,
@@ -1364,36 +1396,13 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
 {
        struct dev_context *devc;
-       uint8_t modestatus;
 
        (void)cb_data;
 
-       sr_source_remove(0);
-
-       if (!(devc = sdi->priv)) {
-               sr_err("%s: sdi->priv was NULL", __func__);
-               return SR_ERR_BUG;
-       }
-
-       /* Stop acquisition. */
-       sigma_set_register(WRITE_MODE, 0x11, devc);
-
-       /* Set SDRAM Read Enable. */
-       sigma_set_register(WRITE_MODE, 0x02, devc);
-
-       /* Get the current position. */
-       sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc);
-
-       /* Check if trigger has fired. */
-       modestatus = sigma_get_register(READ_MODE, devc);
-       if (modestatus & 0x20)
-               devc->state.triggerchunk = devc->state.triggerpos / 512;
-       else
-               devc->state.triggerchunk = -1;
-
-       devc->state.chunks_downloaded = 0;
+       devc = sdi->priv;
+       devc->state.state = SIGMA_IDLE;
 
-       devc->state.state = SIGMA_DOWNLOAD;
+       sr_source_remove(0);
 
        return SR_OK;
 }