]> sigrok.org Git - libsigrok.git/commitdiff
Sigma: Value/mask trigger support in 50 MHz mode.
authorHåvard Espeland <redacted>
Sat, 1 May 2010 20:38:43 +0000 (22:38 +0200)
committerHåvard Espeland <redacted>
Sat, 1 May 2010 21:16:27 +0000 (23:16 +0200)
hardware/asix-sigma/asix-sigma.c
hardware/asix-sigma/asix-sigma.h

index cc77a647a08ac110b2a25497adf17ac76f531bf7..64f637d48058fb1d50eac35ccea1c6f8c2c7a5e4 100644 (file)
@@ -35,7 +35,7 @@
 #define USB_VENDOR_NAME                        "ASIX"
 #define USB_MODEL_NAME                 "SIGMA"
 #define USB_MODEL_VERSION              ""
-#define TRIGGER_TYPES                  "rf"
+#define TRIGGER_TYPES                  "rf10"
 
 static GSList *device_instances = NULL;
 
@@ -49,10 +49,14 @@ static int num_probes = 0;
 static int samples_per_event = 0;
 static int capture_ratio = 50;
 
-/* Single-pin trigger support*/
+/* Single-pin trigger support (100 and 200 MHz).*/
 static uint8_t triggerpin = 1;
 static uint8_t triggerfall = 0;
 
+/* Simple trigger support (<= 50 MHz). */
+static uint16_t triggermask = 1;
+static uint16_t triggervalue = 1;
+
 static uint64_t supported_samplerates[] = {
        KHZ(200),
        KHZ(250),
@@ -245,6 +249,64 @@ static int sigma_read_dram(uint16_t startchunk, size_t numchunks, uint8_t *data)
        return sigma_read(data, numchunks * CHUNK_SIZE);
 }
 
+/* Upload trigger look-up tables to Sigma */
+static int sigma_write_trigger_lut(struct triggerlut *lut)
+{
+       int i;
+       uint8_t tmp[2];
+       uint16_t bit;
+
+       /* Transpose the table and send to Sigma. */
+       for (i = 0; i < 16; ++i) {
+               bit = 1 << i;
+
+               tmp[0] = tmp[1] = 0;
+
+               if (lut->m2d[0] & bit)
+                       tmp[0] |= 0x01;
+               if (lut->m2d[1] & bit)
+                       tmp[0] |= 0x02;
+               if (lut->m2d[2] & bit)
+                       tmp[0] |= 0x04;
+               if (lut->m2d[3] & bit)
+                       tmp[0] |= 0x08;
+
+               if (lut->m3 & bit)
+                       tmp[0] |= 0x10;
+               if (lut->m3s & bit)
+                       tmp[0] |= 0x20;
+               if (lut->m4 & bit)
+                       tmp[0] |= 0x40;
+
+               if (lut->m0d[0] & bit)
+                       tmp[1] |= 0x01;
+               if (lut->m0d[1] & bit)
+                       tmp[1] |= 0x02;
+               if (lut->m0d[2] & bit)
+                       tmp[1] |= 0x04;
+               if (lut->m0d[3] & bit)
+                       tmp[1] |= 0x08;
+
+               if (lut->m1d[0] & bit)
+                       tmp[1] |= 0x10;
+               if (lut->m1d[1] & bit)
+                       tmp[1] |= 0x20;
+               if (lut->m1d[2] & bit)
+                       tmp[1] |= 0x40;
+               if (lut->m1d[3] & bit)
+                       tmp[1] |= 0x80;
+
+               sigma_write_register(WRITE_TRIGGER_SELECT0, tmp, sizeof(tmp));
+               sigma_set_register(WRITE_TRIGGER_SELECT1, 0x30 | i);
+       }
+
+       /* Send the parameters */
+       sigma_write_register(WRITE_TRIGGER_SELECT0, (uint8_t *) &lut->params,
+                            sizeof(lut->params));
+
+       return SIGROK_OK;
+}
+
 /* Generate the bitbang stream for programming the FPGA. */
 static int bin2bitbang(const char *filename,
                       unsigned char **buf, size_t *buf_size)
@@ -515,11 +577,8 @@ static int configure_probes(GSList *probes)
        GSList *l;
        int trigger_set = 0;
 
-       if (cur_samplerate <= MHZ(50)) {
-               g_warning("Trigger support only implemented "
-                         "in 100 and 200 MHz mode.");
-               return SIGROK_ERR;
-       }
+       triggermask = 0;
+       triggervalue = 0;
 
        for (l = probes; l; l = l->next) {
                probe = (struct probe *)l->data;
@@ -527,20 +586,43 @@ static int configure_probes(GSList *probes)
                if (!probe->enabled || !probe->trigger)
                        continue;
 
-               if (trigger_set) {
-                       g_warning("Asix Sigma only supports a single pin trigger "
-                                 "in 100 and 200 MHz mode.");
-                       return SIGROK_ERR;
-               }
+               if (cur_samplerate >= MHZ(100)) {
+                       /* Fast trigger support */
+                       if (trigger_set) {
+                               g_warning("Asix Sigma only supports a single pin trigger "
+                                               "in 100 and 200 MHz mode.");
+                               return SIGROK_ERR;
+                       }
+                       if (probe->trigger[0] == 'f')
+                               triggerfall = 1;
+                       else if (probe->trigger[0] == 'r')
+                               triggerfall = 0;
+                       else {
+                               g_warning("Asix Sigma only supports "
+                                         "rising/falling trigger in 100 "
+                                         "and 200 MHz mode.");
+                               return SIGROK_ERR;
+                       }
 
-               /* Found trigger. */
-               if (probe->trigger[0] == 'f')
-                       triggerfall = 1;
-               else
-                       triggerfall = 0;
+                       triggerpin = probe->index - 1;
+               } else {
+                       /* Normal trigger support */
+                       triggermask |= 1 << (probe->index - 1);
+
+                       if (probe->trigger[0] == '1')
+                               triggervalue |= 1 << (probe->index - 1);
+                       else if (probe->trigger[0] == '0')
+                               triggervalue |= 0 << (probe->index - 1);
+                       else {
+                               g_warning("Asix Sigma only supports "
+                                         "trigger values in <= 50"
+                                         " MHz mode.");
+                               return SIGROK_ERR;
+                       }
+
+               }
 
-               triggerpin = probe->index - 1;
-               trigger_set = 1;
+               ++trigger_set;
        }
 
        return SIGROK_OK;
@@ -652,10 +734,20 @@ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
        uint16_t *event;
        uint16_t cur_sample;
        int triggerts = -1;
+       int triggeroff = 0;
 
-       /* Find in which cluster the trigger occured. */
-       if (triggerpos != -1)
-               triggerts = (triggerpos / 7);
+       if (triggerpos != -1) {
+               if (cur_samplerate <= MHZ(50))
+                       triggerpos -= EVENTS_PER_CLUSTER;
+               else
+                       triggeroff = 3;
+
+               if (triggerpos < 0)
+                       triggerpos = 0;
+
+               /* Find in which cluster the trigger occured. */
+               triggerts = triggerpos / 7;
+       }
 
        /* For each ts. */
        for (i = 0; i < 64; ++i) {
@@ -706,8 +798,6 @@ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
                        }
                }
 
-               *lastsample = samples[n - 1];
-
                /* Send data up to trigger point (if triggered). */
                sent = 0;
                if (i == triggerts) {
@@ -717,7 +807,7 @@ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
                         * in a single event, the trigger does not match the
                         * exact sample.
                         */
-                       tosend = (triggerpos % 7) - 3;
+                       tosend = (triggerpos % 7) - triggeroff;
 
                        if (tosend > 0) {
                                packet.type = DF_LOGIC16;
@@ -741,6 +831,8 @@ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
                packet.length = tosend * sizeof(uint16_t);
                packet.payload = samples + sent;
                session_bus(user_data, &packet);
+
+               *lastsample = samples[n - 1];
        }
 
        return SIGROK_OK;
@@ -825,6 +917,46 @@ static int receive_data(int fd, int revents, void *user_data)
        return TRUE;
 }
 
+/*
+ * Build trigger LUTs used by 50 MHz and lower sample rates for supporting
+ * simple pin change and state triggers. Only two transitions (rise/fall) can be
+ * set at any time, but a full mask and value can be set (0/1).
+ */
+static int build_basic_trigger(struct triggerlut *lut)
+{
+       int i, j, k, bit;
+
+       memset(lut, 0, sizeof(struct triggerlut));
+
+       /* Unknown */
+       lut->m4 = 0xa000;
+
+       /* Set the LUT for controlling value/maske trigger */
+       for (i = 0; i < 4; ++i) {
+               lut->m2d[i] = 0xffff;
+
+               for (j = 0; j < 16; ++j)
+
+                       for (k = 0; k < 4; ++k) {
+                               bit = 1 << (i * 4 + k);
+
+                               if ((triggermask & bit) &&
+                                   (triggervalue & bit) != (j & (1 << k))) {
+                                       lut->m2d[i] &= ~(1 << j);
+                               }
+                       }
+       }
+
+
+       /* Unused when not triggering on transitions */
+       lut->m3 = 0xffff;
+
+       /* Triggertype: event */
+       lut->params.selres = 3;
+
+       return SIGROK_OK;
+}
+
 static int hw_start_acquisition(int device_index, gpointer session_device_id)
 {
        struct sigrok_device_instance *sdi;
@@ -834,6 +966,7 @@ static int hw_start_acquisition(int device_index, gpointer session_device_id)
        int frac;
        uint8_t triggerselect;
        struct triggerinout triggerinout_conf;
+       struct triggerlut lut;
 
        session_device_id = session_device_id;
 
@@ -858,7 +991,9 @@ static int hw_start_acquisition(int device_index, gpointer session_device_id)
 
        /* All other modes. */
        } else if (cur_samplerate <= MHZ(50)) {
-               sigma_set_register(WRITE_TRIGGER_SELECT1, 0x20);
+               build_basic_trigger(&lut);
+
+               sigma_write_trigger_lut(&lut);
 
                triggerselect = (1 << LEDSEL1) | (1 << LEDSEL0);
        }
index 2d38294ea964c5d348a3ae0830aef50e37ab7973..76c143b49794cef40af3b4d8c4738ba6d1dd4632 100644 (file)
@@ -102,4 +102,24 @@ struct triggerinout {
        uint8_t trgin_enable : 1;
 };
 
+struct triggerlut {
+       /* The actual LUTs. */
+       uint16_t m0d[4], m1d[4], m2d[4];
+       uint16_t m3, m3s, m4;
+
+       /* Paramters should be sent as a single register write. */
+       struct {
+               uint8_t selc : 2;
+               uint8_t selpresc : 6;
+
+               uint8_t selinc : 2;
+               uint8_t selres : 2;
+               uint8_t sela : 2;
+               uint8_t selb : 2;
+
+               uint16_t cmpb;
+               uint16_t cmpa;
+       } params;
+};
+
 #endif