]> sigrok.org Git - libsigrok.git/commitdiff
sysclk-lwla: Implement SR_CONF_CLOCK_EDGE setting.
authorDaniel Elstner <redacted>
Wed, 29 Jan 2014 23:31:42 +0000 (00:31 +0100)
committerBert Vermeulen <redacted>
Thu, 30 Jan 2014 11:04:42 +0000 (12:04 +0100)
hardware/sysclk-lwla/api.c
hardware/sysclk-lwla/protocol.c
hardware/sysclk-lwla/protocol.h

index f94edcd697d6bb0388c3311a064d97f34e383eb2..d6c6267a22b1d526e87ecba2e2f7d08cee3931fe 100644 (file)
@@ -33,6 +33,7 @@ static const int32_t hwcaps[] = {
        SR_CONF_LOGIC_ANALYZER,
        SR_CONF_SAMPLERATE,
        SR_CONF_EXTERNAL_CLOCK,
+       SR_CONF_CLOCK_EDGE,
        SR_CONF_TRIGGER_TYPE,
        SR_CONF_TRIGGER_SOURCE,
        SR_CONF_TRIGGER_SLOPE,
@@ -59,9 +60,9 @@ static const uint64_t samplerates[] = {
 static const char *const trigger_source_names[] = { "CH", "TRG" };
 
 /* Names assigned to available trigger slope choices.  Indices must
- * match trigger_slope enum values.
+ * match the signal_edge enum values.
  */
-static const char *const trigger_slope_names[] = { "r", "f" };
+static const char *const signal_edge_names[] = { "r", "f" };
 
 SR_PRIV struct sr_dev_driver sysclk_lwla_driver_info;
 static struct sr_dev_driver *const di = &sysclk_lwla_driver_info;
@@ -234,30 +235,26 @@ static int dev_open(struct sr_dev_inst *sdi)
 static int dev_close(struct sr_dev_inst *sdi)
 {
        struct sr_usb_dev_inst *usb;
-       struct dev_context *devc;
 
        if (!di->priv) {
                sr_err("Driver was not initialized.");
                return SR_ERR;
        }
 
-       usb  = sdi->conn;
-       devc = sdi->priv;
-
+       usb = sdi->conn;
        if (!usb->devhdl)
                return SR_OK;
 
-       /* Trigger download of the shutdown bitstream. */
-       devc->selected_clock_source = CLOCK_SOURCE_NONE;
+       sdi->status = SR_ST_INACTIVE;
 
-       if (lwla_set_clock_source(sdi) != SR_OK)
+       /* Trigger download of the shutdown bitstream. */
+       if (lwla_set_clock_config(sdi) != SR_OK)
                sr_err("Unable to shut down device.");
 
        libusb_release_interface(usb->devhdl, USB_INTERFACE);
        libusb_close(usb->devhdl);
 
        usb->devhdl = NULL;
-       sdi->status = SR_ST_INACTIVE;
 
        return SR_OK;
 }
@@ -291,8 +288,14 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi,
                *data = g_variant_new_uint64(devc->limit_samples);
                break;
        case SR_CONF_EXTERNAL_CLOCK:
-               *data = g_variant_new_boolean(devc->selected_clock_source
-                                               >= CLOCK_SOURCE_EXT_RISE);
+               *data = g_variant_new_boolean(devc->cfg_clock_source
+                                               == CLOCK_EXT_CLK);
+               break;
+       case SR_CONF_CLOCK_EDGE:
+               idx = devc->cfg_clock_edge;
+               if (idx >= G_N_ELEMENTS(signal_edge_names))
+                       return SR_ERR_BUG;
+               *data = g_variant_new_string(signal_edge_names[idx]);
                break;
        case SR_CONF_TRIGGER_SOURCE:
                idx = devc->cfg_trigger_source;
@@ -302,9 +305,9 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi,
                break;
        case SR_CONF_TRIGGER_SLOPE:
                idx = devc->cfg_trigger_slope;
-               if (idx >= G_N_ELEMENTS(trigger_slope_names))
+               if (idx >= G_N_ELEMENTS(signal_edge_names))
                        return SR_ERR_BUG;
-               *data = g_variant_new_string(trigger_slope_names[idx]);
+               *data = g_variant_new_string(signal_edge_names[idx]);
                break;
        default:
                return SR_ERR_NA;
@@ -367,14 +370,15 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi,
                devc->limit_samples = value;
                break;
        case SR_CONF_EXTERNAL_CLOCK:
-               if (g_variant_get_boolean(data)) {
-                       sr_info("Enabling external clock.");
-                       /* TODO: Allow the external clock to be inverted */
-                       devc->selected_clock_source = CLOCK_SOURCE_EXT_RISE;
-               } else {
-                       sr_info("Disabling external clock.");
-                       devc->selected_clock_source = CLOCK_SOURCE_INT;
-               }
+               devc->cfg_clock_source = (g_variant_get_boolean(data))
+                       ? CLOCK_EXT_CLK : CLOCK_INTERNAL;
+               break;
+       case SR_CONF_CLOCK_EDGE:
+               idx = lookup_index(data, signal_edge_names,
+                                  G_N_ELEMENTS(signal_edge_names));
+               if (idx < 0)
+                       return SR_ERR_ARG;
+               devc->cfg_clock_edge = idx;
                break;
        case SR_CONF_TRIGGER_SOURCE:
                idx = lookup_index(data, trigger_source_names,
@@ -384,8 +388,8 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi,
                devc->cfg_trigger_source = idx;
                break;
        case SR_CONF_TRIGGER_SLOPE:
-               idx = lookup_index(data, trigger_slope_names,
-                                  G_N_ELEMENTS(trigger_slope_names));
+               idx = lookup_index(data, signal_edge_names,
+                                  G_N_ELEMENTS(signal_edge_names));
                if (idx < 0)
                        return SR_ERR_ARG;
                devc->cfg_trigger_slope = idx;
@@ -469,7 +473,7 @@ static int config_commit(const struct sr_dev_inst *sdi)
                return SR_ERR;
        }
 
-       return lwla_set_clock_source(sdi);
+       return lwla_set_clock_config(sdi);
 }
 
 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
@@ -506,8 +510,9 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
                                           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));
+       case SR_CONF_CLOCK_EDGE:
+               *data = g_variant_new_strv(signal_edge_names,
+                                          G_N_ELEMENTS(signal_edge_names));
                break;
        default:
                return SR_ERR_NA;
index c4d99d82ab0d10c8c64b866b7cb9f4038373e564..75b3806362c573ef2d5535b43416d9fe71e5f287 100644 (file)
@@ -29,7 +29,7 @@
 /* Number of 64-bit words read from the capture status memory. */
 #define CAP_STAT_LEN 5
 
-/* The bitstream filenames are indexed by the clock source enumeration.
+/* The bitstream filenames are indexed by the clock_config enumeration.
  */
 static const char bitstream_map[][32] = {
        "sysclk-lwla1034-off.rbf",
@@ -107,8 +107,8 @@ static int capture_setup(const struct sr_dev_inst *sdi)
        /* 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; 
+               case EDGE_POSITIVE: trigger_mask |= (uint64_t)1 << 35; break; 
+               case EDGE_NEGATIVE: trigger_mask |= (uint64_t)1 << 34; break; 
                }
 
        command[19] = LWLA_WORD_0(trigger_mask);
@@ -702,14 +702,10 @@ SR_PRIV int lwla_init_device(const struct sr_dev_inst *sdi)
 
        devc = sdi->priv;
 
-       /* Select internal clock if it hasn't been set yet */
-       if (devc->selected_clock_source == CLOCK_SOURCE_NONE)
-               devc->selected_clock_source = CLOCK_SOURCE_INT;
-
        /* Force reload of bitstream */
-       devc->cur_clock_source = CLOCK_SOURCE_NONE;
+       devc->cur_clock_config = CONF_CLOCK_NONE;
 
-       ret = lwla_set_clock_source(sdi);
+       ret = lwla_set_clock_config(sdi);
 
        if (ret != SR_OK)
                return ret;
@@ -742,29 +738,31 @@ SR_PRIV int lwla_init_device(const struct sr_dev_inst *sdi)
        return ret;
 }
 
-/* Select the LWLA clock source.  If the clock source changed from the
- * previous setting, this will download a new bitstream to the FPGA.
+/* Select the LWLA clock configuration.  If the clock source changed from
+ * the previous setting, this will download a new bitstream to the FPGA.
  */
-SR_PRIV int lwla_set_clock_source(const struct sr_dev_inst *sdi)
+SR_PRIV int lwla_set_clock_config(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
        int ret;
-       enum clock_source selected;
-       size_t idx;
+       enum clock_config choice;
 
        devc = sdi->priv;
-       selected = devc->selected_clock_source;
 
-       if (devc->cur_clock_source != selected) {
-               devc->cur_clock_source = CLOCK_SOURCE_NONE;
-               idx = selected;
-               if (idx >= G_N_ELEMENTS(bitstream_map)) {
-                       sr_err("Clock source (%d) out of range", selected);
-                       return SR_ERR_BUG;
-               }
-               ret = lwla_send_bitstream(sdi->conn, bitstream_map[idx]);
+       if (sdi->status == SR_ST_INACTIVE)
+               choice = CONF_CLOCK_NONE;
+       else if (devc->cfg_clock_source == CLOCK_INTERNAL)
+               choice = CONF_CLOCK_INT;
+       else if (devc->cfg_clock_edge == EDGE_POSITIVE)
+               choice = CONF_CLOCK_EXT_RISE;
+       else
+               choice = CONF_CLOCK_EXT_FALL;
+
+       if (choice != devc->cur_clock_config) {
+               devc->cur_clock_config = CONF_CLOCK_NONE;
+               ret = lwla_send_bitstream(sdi->conn, bitstream_map[choice]);
                if (ret == SR_OK)
-                       devc->cur_clock_source = selected;
+                       devc->cur_clock_config = choice;
                return ret;
        }
        return SR_OK;
@@ -798,8 +796,7 @@ SR_PRIV int lwla_setup_acquisition(const struct sr_dev_inst *sdi)
        } else
                acq->samples_max = MAX_LIMIT_SAMPLES;
 
-       switch (devc->cur_clock_source) {
-       case CLOCK_SOURCE_INT:
+       if (devc->cfg_clock_source == CLOCK_INTERNAL) {
                sr_info("Internal clock, samplerate %" PRIu64 ".",
                        devc->samplerate);
                if (devc->samplerate == 0)
@@ -814,18 +811,13 @@ SR_PRIV int lwla_setup_acquisition(const struct sr_dev_inst *sdi)
                else if (devc->limit_samples == 0 && devc->limit_msec > 0)
                        acq->samples_max = devc->limit_msec
                                        * devc->samplerate / 1000;
-               break;
-       case CLOCK_SOURCE_EXT_FALL:
-               sr_info("External clock, falling edge.");
-               acq->bypass_clockdiv = TRUE;
-               break;
-       case CLOCK_SOURCE_EXT_RISE:
-               sr_info("External clock, rising edge.");
+       } else {
                acq->bypass_clockdiv = TRUE;
-               break;
-       default:
-               sr_err("No valid clock source has been configured.");
-               return SR_ERR;
+
+               if (devc->cfg_clock_edge == EDGE_NEGATIVE)
+                       sr_info("External clock, falling edge.");
+               else
+                       sr_info("External clock, rising edge.");
        }
 
        regvals[0].reg = REG_MEM_CTRL2;
index c410e60bdb68709190d7a6393919e4085a3d694d..61940be6668a5c9d14215cb388686512981327f7 100644 (file)
  */
 #define MAX_LIMIT_MSEC         (UINT64_C(1) << 32)
 
-/** LWLA clock sources.
+/** LWLA1034 FPGA clock configurations.
+ */
+enum clock_config {
+       CONF_CLOCK_NONE,
+       CONF_CLOCK_INT,
+       CONF_CLOCK_EXT_RISE,
+       CONF_CLOCK_EXT_FALL,
+};
+
+/** Available clock sources.
  */
 enum clock_source {
-       CLOCK_SOURCE_NONE,
-       CLOCK_SOURCE_INT,
-       CLOCK_SOURCE_EXT_RISE,
-       CLOCK_SOURCE_EXT_FALL,
+       CLOCK_INTERNAL,
+       CLOCK_EXT_CLK,
 };
 
 /** Available trigger sources.
@@ -117,11 +124,11 @@ enum trigger_source {
        TRIGGER_EXT_TRG,
 };
 
-/** Available edge choices for the external trigger.
+/** Available edge choices for the external clock and trigger inputs.
  */
-enum trigger_slope {
-       SLOPE_POSITIVE = 0,
-       SLOPE_NEGATIVE,
+enum signal_edge {
+       EDGE_POSITIVE = 0,
+       EDGE_NEGATIVE,
 };
 
 /** LWLA device states.
@@ -223,15 +230,18 @@ struct dev_context {
 
        enum device_state state;
 
-       /** The currently configured clock source of the device. */
-       enum clock_source cur_clock_source;
-       /** The clock source selected by the user. */
-       enum clock_source selected_clock_source;
+       /** The currently active clock configuration of the device. */
+       enum clock_config cur_clock_config;
+
+       /** Clock source configuration setting. */
+       enum clock_source cfg_clock_source;
+       /** Clock edge configuration setting. */
+       enum signal_edge cfg_clock_edge;
 
        /** Trigger source configuration setting. */
        enum trigger_source cfg_trigger_source;
        /** Trigger slope configuration setting. */
-       enum trigger_slope cfg_trigger_slope;
+       enum signal_edge cfg_trigger_slope;
 
        /* Indicates that stopping the acquisition is currently in progress. */
        gboolean stopping_in_progress;
@@ -244,7 +254,7 @@ SR_PRIV struct acquisition_state *lwla_alloc_acquisition_state(void);
 SR_PRIV void lwla_free_acquisition_state(struct acquisition_state *acq);
 
 SR_PRIV int lwla_init_device(const struct sr_dev_inst *sdi);
-SR_PRIV int lwla_set_clock_source(const struct sr_dev_inst *sdi);
+SR_PRIV int lwla_set_clock_config(const struct sr_dev_inst *sdi);
 SR_PRIV int lwla_setup_acquisition(const struct sr_dev_inst *sdi);
 SR_PRIV int lwla_start_acquisition(const struct sr_dev_inst *sdi);
 SR_PRIV int lwla_abort_acquisition(const struct sr_dev_inst *sdi);