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:
Daniel Elstner 2014-01-26 21:42:22 +01:00
parent e0df15d436
commit e6e54bd253
3 changed files with 100 additions and 4 deletions

View File

@ -34,6 +34,8 @@ static const int32_t hwcaps[] = {
SR_CONF_SAMPLERATE, SR_CONF_SAMPLERATE,
SR_CONF_EXTERNAL_CLOCK, SR_CONF_EXTERNAL_CLOCK,
SR_CONF_TRIGGER_TYPE, SR_CONF_TRIGGER_TYPE,
SR_CONF_TRIGGER_SOURCE,
SR_CONF_TRIGGER_SLOPE,
SR_CONF_LIMIT_MSEC, SR_CONF_LIMIT_MSEC,
SR_CONF_LIMIT_SAMPLES, SR_CONF_LIMIT_SAMPLES,
}; };
@ -51,6 +53,16 @@ static const uint64_t samplerates[] = {
SR_HZ(500), SR_HZ(200), SR_HZ(100), 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; SR_PRIV struct sr_dev_driver sysclk_lwla_driver_info;
static struct sr_dev_driver *const di = &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) const struct sr_probe_group *probe_group)
{ {
struct dev_context *devc; struct dev_context *devc;
size_t idx;
(void)probe_group; (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 *data = g_variant_new_boolean(devc->selected_clock_source
>= CLOCK_SOURCE_EXT_RISE); >= CLOCK_SOURCE_EXT_RISE);
break; 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: default:
return SR_ERR_NA; 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; 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, static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi,
const struct sr_probe_group *probe_group) const struct sr_probe_group *probe_group)
{ {
uint64_t value; uint64_t value;
struct dev_context *devc; struct dev_context *devc;
int idx;
(void)probe_group; (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; devc->selected_clock_source = CLOCK_SOURCE_INT;
} }
break; 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: default:
return SR_ERR_NA; 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: case SR_CONF_TRIGGER_TYPE:
*data = g_variant_new_string(TRIGGER_TYPES); *data = g_variant_new_string(TRIGGER_TYPES);
break; 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: default:
return SR_ERR_NA; return SR_ERR_NA;
} }

View File

@ -63,6 +63,7 @@ static int capture_setup(const struct sr_dev_inst *sdi)
struct dev_context *devc; struct dev_context *devc;
struct acquisition_state *acq; struct acquisition_state *acq;
uint64_t divider_count; uint64_t divider_count;
uint64_t trigger_mask;
uint64_t memory_limit; uint64_t memory_limit;
uint16_t command[3 + 10*4]; 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[17] = LWLA_WORD_2(devc->trigger_edge_mask);
command[18] = LWLA_WORD_3(devc->trigger_edge_mask); command[18] = LWLA_WORD_3(devc->trigger_edge_mask);
command[19] = LWLA_WORD_0(devc->trigger_mask); trigger_mask = devc->trigger_mask;
command[20] = LWLA_WORD_1(devc->trigger_mask); /* Set bits to select external TRG input edge. */
command[21] = LWLA_WORD_2(devc->trigger_mask); if (devc->cfg_trigger_source == TRIGGER_EXT_TRG)
command[22] = LWLA_WORD_3(devc->trigger_mask); 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 /* Set the capture memory full threshold. This is slightly less
* than the actual maximum, most likely in order to compensate for * than the actual maximum, most likely in order to compensate for

View File

@ -110,6 +110,20 @@ enum clock_source {
CLOCK_SOURCE_EXT_FALL, 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. /** LWLA device states.
*/ */
enum device_state { enum device_state {
@ -214,6 +228,11 @@ struct dev_context {
/** The clock source selected by the user. */ /** The clock source selected by the user. */
enum clock_source selected_clock_source; 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. */ /* Indicates that stopping the acquisition is currently in progress. */
gboolean stopping_in_progress; gboolean stopping_in_progress;