dslogic: Add support for external clock edge selection.

This commit expands support for acquisition using an external clock,
now allowing the user to select the clock edge.

Signed-off-by: Diego Asanza <f.asanza@gmail.com>
This commit is contained in:
Diego Asanza 2016-05-08 10:07:05 +02:00 committed by Uwe Hermann
parent 41dc254778
commit d9a58763d6
5 changed files with 63 additions and 3 deletions

View File

@ -143,6 +143,7 @@ static const uint32_t dslogic_devopts[] = {
SR_CONF_TRIGGER_MATCH | SR_CONF_LIST, SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET, SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
SR_CONF_EXTERNAL_CLOCK | SR_CONF_GET | 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
}; };
static const int32_t soft_trigger_matches[] = { static const int32_t soft_trigger_matches[] = {
@ -153,6 +154,13 @@ static const int32_t soft_trigger_matches[] = {
SR_TRIGGER_EDGE, SR_TRIGGER_EDGE,
}; };
/* Names assigned to available edge slope choices.
*/
static const char *const signal_edge_names[] = {
[DS_EDGE_RISING] = "rising",
[DS_EDGE_FALLING] = "falling",
};
static const struct { static const struct {
int range; int range;
gdouble low; gdouble low;
@ -574,6 +582,12 @@ static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *s
case SR_CONF_CONTINUOUS: case SR_CONF_CONTINUOUS:
*data = g_variant_new_boolean(devc->dslogic_continuous_mode); *data = g_variant_new_boolean(devc->dslogic_continuous_mode);
break; break;
case SR_CONF_CLOCK_EDGE:
i = devc->dslogic_clock_edge;
if (i >= ARRAY_SIZE(signal_edge_names))
return SR_ERR_BUG;
*data = g_variant_new_string(signal_edge_names[0]);//idx]);
break;
default: default:
return SR_ERR_NA; return SR_ERR_NA;
} }
@ -581,6 +595,28 @@ static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *s
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(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi, static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
const struct sr_channel_group *cg) const struct sr_channel_group *cg)
{ {
@ -645,6 +681,13 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd
case SR_CONF_CONTINUOUS: case SR_CONF_CONTINUOUS:
devc->dslogic_continuous_mode = g_variant_get_boolean(data); devc->dslogic_continuous_mode = g_variant_get_boolean(data);
break; break;
case SR_CONF_CLOCK_EDGE:
i = lookup_index(data, signal_edge_names,
ARRAY_SIZE(signal_edge_names));
if (i < 0)
return SR_ERR_ARG;
devc->dslogic_clock_edge = i;
break;
default: default:
ret = SR_ERR_NA; ret = SR_ERR_NA;
} }
@ -709,6 +752,10 @@ static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *
soft_trigger_matches, ARRAY_SIZE(soft_trigger_matches), soft_trigger_matches, ARRAY_SIZE(soft_trigger_matches),
sizeof(int32_t)); sizeof(int32_t));
break; break;
case SR_CONF_CLOCK_EDGE:
*data = g_variant_new_strv(signal_edge_names,
ARRAY_SIZE(signal_edge_names));
break;
default: default:
return SR_ERR_NA; return SR_ERR_NA;
} }

View File

@ -337,8 +337,10 @@ SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi)
* 6 1 = samplerate 400MHz * 6 1 = samplerate 400MHz
* 5 1 = samplerate 200MHz or analog mode * 5 1 = samplerate 200MHz or analog mode
* 4 0 = logic, 1 = dso or analog * 4 0 = logic, 1 = dso or analog
* 2-3 unused * 3 unused
* 1 0 = internal clock, 1 = external clock * 1-2 00 = internal clock,
* 01 = external clock rising,
* 11 = external clock falling
* 0 1 = trigger enabled * 0 1 = trigger enabled
*/ */
v16 = 0x0000; v16 = 0x0000;
@ -350,8 +352,12 @@ SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi)
v16 = 1 << 13; v16 = 1 << 13;
if (devc->dslogic_continuous_mode) if (devc->dslogic_continuous_mode)
v16 |= 1 << 12; v16 |= 1 << 12;
if (devc->dslogic_external_clock) if (devc->dslogic_external_clock){
v16 |= 1 << 1; v16 |= 1 << 1;
if (devc->dslogic_clock_edge == DS_EDGE_FALLING){
v16 |= 1 << 2;
}
}
WL16(&cfg.mode, v16); WL16(&cfg.mode, v16);
v32 = ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate); v32 = ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);

View File

@ -47,6 +47,11 @@ enum {
DS_VOLTAGE_RANGE_5_V, /* 5V logic */ DS_VOLTAGE_RANGE_5_V, /* 5V logic */
}; };
enum{
DS_EDGE_RISING,
DS_EDGE_FALLING
};
struct dslogic_version { struct dslogic_version {
uint8_t major; uint8_t major;
uint8_t minor; uint8_t minor;

View File

@ -307,6 +307,7 @@ SR_PRIV struct dev_context *fx2lafw_dev_new(void)
devc->capture_ratio = 0; devc->capture_ratio = 0;
devc->sample_wide = FALSE; devc->sample_wide = FALSE;
devc->dslogic_continuous_mode = FALSE; devc->dslogic_continuous_mode = FALSE;
devc->dslogic_clock_edge = DS_EDGE_RISING;
devc->stl = NULL; devc->stl = NULL;
return devc; return devc;

View File

@ -137,6 +137,7 @@ struct dev_context {
uint32_t trigger_pos; uint32_t trigger_pos;
gboolean dslogic_external_clock; gboolean dslogic_external_clock;
gboolean dslogic_continuous_mode; gboolean dslogic_continuous_mode;
int dslogic_clock_edge;
int dslogic_voltage_threshold; int dslogic_voltage_threshold;
}; };