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,
};
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;
const struct sr_probe_group *probe_group)
{
struct dev_context *devc;
+ size_t idx;
(void)probe_group;
*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;
}
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;
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;
}
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;
}
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];
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