sysclk-lwla: Add support for external trigger input.
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).
This commit is contained in:
parent
e0df15d436
commit
e6e54bd253
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue