]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/openbench-logic-sniffer/api.c
ols: Make external clock setting queriable
[libsigrok.git] / src / hardware / openbench-logic-sniffer / api.c
index dbf7296a8453e83def8607bd176d502eb5a61483..23f68c57545395477e1b9dc9bf8431f16f8e4493 100644 (file)
@@ -36,7 +36,8 @@ static const uint32_t devopts[] = {
        SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
        SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
        SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
-       SR_CONF_EXTERNAL_CLOCK | SR_CONF_SET,
+       SR_CONF_EXTERNAL_CLOCK | SR_CONF_GET | SR_CONF_SET,
+       SR_CONF_CLOCK_EDGE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
        SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
        SR_CONF_SWAP | SR_CONF_SET,
        SR_CONF_RLE | SR_CONF_GET | SR_CONF_SET,
@@ -47,6 +48,11 @@ static const int32_t trigger_matches[] = {
        SR_TRIGGER_ONE,
 };
 
+static const char* external_clock_edges[] = {
+       "rising", // positive edge
+       "falling" // negative edge
+};
+
 #define STR_PATTERN_NONE     "None"
 #define STR_PATTERN_EXTERNAL "External"
 #define STR_PATTERN_INTERNAL "Internal"
@@ -223,6 +229,14 @@ static int config_get(uint32_t key, GVariant **data,
        case SR_CONF_RLE:
                *data = g_variant_new_boolean(devc->capture_flags & CAPTURE_FLAG_RLE ? TRUE : FALSE);
                break;
+       case SR_CONF_EXTERNAL_CLOCK:
+               *data = g_variant_new_boolean(
+                       devc->capture_flags & CAPTURE_FLAG_CLOCK_EXTERNAL ? TRUE : FALSE);
+               break;
+       case SR_CONF_CLOCK_EDGE:
+               *data = g_variant_new_string(external_clock_edges[
+                       devc->capture_flags & CAPTURE_FLAG_INVERT_EXT_CLOCK ? 1 : 0]);
+               break;
        default:
                return SR_ERR_NA;
        }
@@ -266,6 +280,16 @@ static int config_set(uint32_t key, GVariant *data,
                        devc->capture_flags &= ~CAPTURE_FLAG_CLOCK_EXTERNAL;
                }
                break;
+       case SR_CONF_CLOCK_EDGE:
+               stropt = g_variant_get_string(data, NULL);
+               if (!strcmp(stropt, external_clock_edges[1])) {
+                       sr_info("Triggering on falling edge of external clock.");
+                       devc->capture_flags |= CAPTURE_FLAG_INVERT_EXT_CLOCK;
+               } else {
+                       sr_info("Triggering on rising edge of external clock.");
+                       devc->capture_flags &= ~CAPTURE_FLAG_INVERT_EXT_CLOCK;
+               }
+               break;
        case SR_CONF_PATTERN_MODE:
                stropt = g_variant_get_string(data, NULL);
                if (!strcmp(stropt, STR_PATTERN_NONE)) {
@@ -325,6 +349,9 @@ static int config_list(uint32_t key, GVariant **data,
        case SR_CONF_TRIGGER_MATCH:
                *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
                break;
+       case SR_CONF_CLOCK_EDGE:
+               *data = std_gvar_array_str(ARRAY_AND_SIZE(external_clock_edges));
+               break;
        case SR_CONF_PATTERN_MODE:
                *data = g_variant_new_strv(ARRAY_AND_SIZE(patterns));
                break;
@@ -358,7 +385,7 @@ static int config_list(uint32_t key, GVariant **data,
        return SR_OK;
 }
 
-static int set_trigger(const struct sr_dev_inst *sdi, int stage)
+static int set_basic_trigger(const struct sr_dev_inst *sdi, int stage)
 {
        struct dev_context *devc;
        struct sr_serial_dev_inst *serial;
@@ -367,7 +394,7 @@ static int set_trigger(const struct sr_dev_inst *sdi, int stage)
        devc = sdi->priv;
        serial = sdi->conn;
 
-       cmd = CMD_SET_TRIGGER_MASK + stage * 4;
+       cmd = CMD_SET_BASIC_TRIGGER_MASK0 + stage * 4;
        arg[0] = devc->trigger_mask[stage] & 0xff;
        arg[1] = (devc->trigger_mask[stage] >> 8) & 0xff;
        arg[2] = (devc->trigger_mask[stage] >> 16) & 0xff;
@@ -375,7 +402,7 @@ static int set_trigger(const struct sr_dev_inst *sdi, int stage)
        if (send_longcommand(serial, cmd, arg) != SR_OK)
                return SR_ERR;
 
-       cmd = CMD_SET_TRIGGER_VALUE + stage * 4;
+       cmd = CMD_SET_BASIC_TRIGGER_VALUE0 + stage * 4;
        arg[0] = devc->trigger_value[stage] & 0xff;
        arg[1] = (devc->trigger_value[stage] >> 8) & 0xff;
        arg[2] = (devc->trigger_value[stage] >> 16) & 0xff;
@@ -383,7 +410,7 @@ static int set_trigger(const struct sr_dev_inst *sdi, int stage)
        if (send_longcommand(serial, cmd, arg) != SR_OK)
                return SR_ERR;
 
-       cmd = CMD_SET_TRIGGER_CONFIG + stage * 4;
+       cmd = CMD_SET_BASIC_TRIGGER_CONFIG0 + stage * 4;
        arg[0] = arg[1] = arg[3] = 0x00;
        arg[2] = stage;
        if (stage == devc->num_stages)
@@ -443,13 +470,13 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
                devc->trigger_at_smpl = (readcount - delaycount) * 4 - devc->num_stages;
                for (i = 0; i <= devc->num_stages; i++) {
                        sr_dbg("Setting OLS stage %d trigger.", i);
-                       if ((ret = set_trigger(sdi, i)) != SR_OK)
+                       if ((ret = set_basic_trigger(sdi, i)) != SR_OK)
                                return ret;
                }
        } else {
                /* No triggers configured, force trigger on first stage. */
                sr_dbg("Forcing trigger at stage 0.");
-               if ((ret = set_trigger(sdi, 0)) != SR_OK)
+               if ((ret = set_basic_trigger(sdi, 0)) != SR_OK)
                        return ret;
                delaycount = readcount;
        }
@@ -491,16 +518,21 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
        }
 
        /* Flag register. */
-       sr_dbg("Setting intpat %s, extpat %s, RLE %s, noise_filter %s, demux %s",
+       sr_dbg("Setting intpat %s, extpat %s, RLE %s, noise_filter %s, demux %s, %s clock%s",
                        devc->capture_flags & CAPTURE_FLAG_INTERNAL_TEST_MODE ? "on": "off",
                        devc->capture_flags & CAPTURE_FLAG_EXTERNAL_TEST_MODE ? "on": "off",
                        devc->capture_flags & CAPTURE_FLAG_RLE ? "on" : "off",
                        devc->capture_flags & CAPTURE_FLAG_NOISE_FILTER ? "on": "off",
-                       devc->capture_flags & CAPTURE_FLAG_DEMUX ? "on" : "off");
+                       devc->capture_flags & CAPTURE_FLAG_DEMUX ? "on" : "off",
+                       devc->capture_flags & CAPTURE_FLAG_CLOCK_EXTERNAL ? "external" : "internal",
+                       devc->capture_flags & CAPTURE_FLAG_CLOCK_EXTERNAL ? (devc->capture_flags & CAPTURE_FLAG_INVERT_EXT_CLOCK
+                               ? " on falling edge" : "on rising edge") : "");
+
        /*
         * Enable/disable OLS channel groups in the flag register according
         * to the channel mask. 1 means "disable channel".
         */
+       devc->capture_flags &= ~0x3c;
        devc->capture_flags |= ~(ols_changrp_mask << 2) & 0x3c;
 
        /* RLE mode is always zero, for now. */
@@ -512,7 +544,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
                return SR_ERR;
 
        /* Start acquisition on the device. */
-       if (send_shortcommand(serial, CMD_RUN) != SR_OK)
+       if (send_shortcommand(serial, CMD_ARM_BASIC_TRIGGER) != SR_OK)
                return SR_ERR;
 
        /* Reset all operational states. */