]> sigrok.org Git - libsigrok.git/commitdiff
sysclk-lwla: Add support for external trigger input.
authorDaniel Elstner <redacted>
Sun, 26 Jan 2014 20:42:22 +0000 (21:42 +0100)
committerDaniel Elstner <redacted>
Tue, 28 Jan 2014 22:34:53 +0000 (23:34 +0100)
Implement the configuration setting TRIGGER_SOURCE with the
choices CH (logic channels) and TRG (external trigger input).
Also implement the TRIGGER_SLOPE setting for selecting the
edge to trigger on (rising or falling).

hardware/sysclk-lwla/api.c
hardware/sysclk-lwla/protocol.c
hardware/sysclk-lwla/protocol.h

index d17408d92343eec298de5558691369a9b7c18c42..f94edcd697d6bb0388c3311a064d97f34e383eb2 100644 (file)
@@ -34,6 +34,8 @@ static const int32_t hwcaps[] = {
        SR_CONF_SAMPLERATE,
        SR_CONF_EXTERNAL_CLOCK,
        SR_CONF_TRIGGER_TYPE,
+       SR_CONF_TRIGGER_SOURCE,
+       SR_CONF_TRIGGER_SLOPE,
        SR_CONF_LIMIT_MSEC,
        SR_CONF_LIMIT_SAMPLES,
 };
@@ -51,6 +53,16 @@ static const uint64_t samplerates[] = {
        SR_HZ(500),  SR_HZ(200),  SR_HZ(100),
 };
 
+/* Names assigned to available trigger sources.  Indices must match
+ * trigger_source enum values.
+ */
+static const char *const trigger_source_names[] = { "CH", "TRG" };
+
+/* Names assigned to available trigger slope choices.  Indices must
+ * match trigger_slope enum values.
+ */
+static const char *const trigger_slope_names[] = { "r", "f" };
+
 SR_PRIV struct sr_dev_driver sysclk_lwla_driver_info;
 static struct sr_dev_driver *const di = &sysclk_lwla_driver_info;
 
@@ -259,6 +271,7 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi,
                      const struct sr_probe_group *probe_group)
 {
        struct dev_context *devc;
+       size_t idx;
 
        (void)probe_group;
 
@@ -281,6 +294,18 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi,
                *data = g_variant_new_boolean(devc->selected_clock_source
                                                >= CLOCK_SOURCE_EXT_RISE);
                break;
+       case SR_CONF_TRIGGER_SOURCE:
+               idx = devc->cfg_trigger_source;
+               if (idx >= G_N_ELEMENTS(trigger_source_names))
+                       return SR_ERR_BUG;
+               *data = g_variant_new_string(trigger_source_names[idx]);
+               break;
+       case SR_CONF_TRIGGER_SLOPE:
+               idx = devc->cfg_trigger_slope;
+               if (idx >= G_N_ELEMENTS(trigger_slope_names))
+                       return SR_ERR_BUG;
+               *data = g_variant_new_string(trigger_slope_names[idx]);
+               break;
        default:
                return SR_ERR_NA;
        }
@@ -288,11 +313,32 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi,
        return SR_OK;
 }
 
+/* Helper for mapping a string-typed configuration value to an index
+ * within a table of possible values.
+ */
+static int lookup_index(GVariant *value, const char *const *table, int len)
+{
+       const char *entry;
+       int i;
+
+       entry = g_variant_get_string(value, NULL);
+       if (!entry)
+               return -1;
+
+       /* Linear search is fine for very small tables. */
+       for (i = 0; i < len; ++i) {
+               if (strcmp(entry, table[i]) == 0)
+                       return i;
+       }
+       return -1;
+}
+
 static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi,
                      const struct sr_probe_group *probe_group)
 {
        uint64_t value;
        struct dev_context *devc;
+       int idx;
 
        (void)probe_group;
 
@@ -330,6 +376,20 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi,
                        devc->selected_clock_source = CLOCK_SOURCE_INT;
                }
                break;
+       case SR_CONF_TRIGGER_SOURCE:
+               idx = lookup_index(data, trigger_source_names,
+                                  G_N_ELEMENTS(trigger_source_names));
+               if (idx < 0)
+                       return SR_ERR_ARG;
+               devc->cfg_trigger_source = idx;
+               break;
+       case SR_CONF_TRIGGER_SLOPE:
+               idx = lookup_index(data, trigger_slope_names,
+                                  G_N_ELEMENTS(trigger_slope_names));
+               if (idx < 0)
+                       return SR_ERR_ARG;
+               devc->cfg_trigger_slope = idx;
+               break;
        default:
                return SR_ERR_NA;
        }
@@ -441,6 +501,14 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
        case SR_CONF_TRIGGER_TYPE:
                *data = g_variant_new_string(TRIGGER_TYPES);
                break;
+       case SR_CONF_TRIGGER_SOURCE:
+               *data = g_variant_new_strv(trigger_source_names,
+                                          G_N_ELEMENTS(trigger_source_names));
+               break;
+       case SR_CONF_TRIGGER_SLOPE:
+               *data = g_variant_new_strv(trigger_slope_names,
+                                          G_N_ELEMENTS(trigger_slope_names));
+               break;
        default:
                return SR_ERR_NA;
        }
index 5b1f2483e6ba0b38a875a0f0a1ef6b41c99d7ef0..c4d99d82ab0d10c8c64b866b7cb9f4038373e564 100644 (file)
@@ -63,6 +63,7 @@ static int capture_setup(const struct sr_dev_inst *sdi)
        struct dev_context *devc;
        struct acquisition_state *acq;
        uint64_t divider_count;
+       uint64_t trigger_mask;
        uint64_t memory_limit;
        uint16_t command[3 + 10*4];
 
@@ -102,10 +103,18 @@ static int capture_setup(const struct sr_dev_inst *sdi)
        command[17] = LWLA_WORD_2(devc->trigger_edge_mask);
        command[18] = LWLA_WORD_3(devc->trigger_edge_mask);
 
-       command[19] = LWLA_WORD_0(devc->trigger_mask);
-       command[20] = LWLA_WORD_1(devc->trigger_mask);
-       command[21] = LWLA_WORD_2(devc->trigger_mask);
-       command[22] = LWLA_WORD_3(devc->trigger_mask);
+       trigger_mask = devc->trigger_mask;
+       /* Set bits to select external TRG input edge. */
+       if (devc->cfg_trigger_source == TRIGGER_EXT_TRG)
+               switch (devc->cfg_trigger_slope) {
+               case SLOPE_POSITIVE: trigger_mask |= (uint64_t)1 << 35; break; 
+               case SLOPE_NEGATIVE: trigger_mask |= (uint64_t)1 << 34; break; 
+               }
+
+       command[19] = LWLA_WORD_0(trigger_mask);
+       command[20] = LWLA_WORD_1(trigger_mask);
+       command[21] = LWLA_WORD_2(trigger_mask);
+       command[22] = LWLA_WORD_3(trigger_mask);
 
        /* Set the capture memory full threshold. This is slightly less
         * than the actual maximum, most likely in order to compensate for
index 762a17b595c5d71fb4a67ceee9a1a350f899eec1..c410e60bdb68709190d7a6393919e4085a3d694d 100644 (file)
@@ -110,6 +110,20 @@ enum clock_source {
        CLOCK_SOURCE_EXT_FALL,
 };
 
+/** Available trigger sources.
+ */
+enum trigger_source {
+       TRIGGER_CHANNELS = 0,
+       TRIGGER_EXT_TRG,
+};
+
+/** Available edge choices for the external trigger.
+ */
+enum trigger_slope {
+       SLOPE_POSITIVE = 0,
+       SLOPE_NEGATIVE,
+};
+
 /** LWLA device states.
  */
 enum device_state {
@@ -214,6 +228,11 @@ struct dev_context {
        /** The clock source selected by the user. */
        enum clock_source selected_clock_source;
 
+       /** Trigger source configuration setting. */
+       enum trigger_source cfg_trigger_source;
+       /** Trigger slope configuration setting. */
+       enum trigger_slope cfg_trigger_slope;
+
        /* Indicates that stopping the acquisition is currently in progress. */
        gboolean stopping_in_progress;