dslogic: Fixed voltage selection

This commit is contained in:
Joel Holdsworth 2017-06-13 16:27:03 -06:00 committed by Uwe Hermann
parent 3c749da174
commit 1ee7074616
5 changed files with 82 additions and 68 deletions

View File

@ -75,12 +75,11 @@ static const char *const signal_edge_names[] = {
};
static const struct {
int range;
gdouble low;
gdouble high;
} volt_thresholds[] = {
{ DS_VOLTAGE_RANGE_18_33_V, 0.7, 1.4 },
{ DS_VOLTAGE_RANGE_5_V, 1.4, 3.6 },
} dslogic_voltage_thresholds[] = {
{ 0.7, 1.4 },
{ 1.4, 3.6 },
};
static const uint64_t samplerates[] = {
@ -374,6 +373,9 @@ static int dev_open(struct sr_dev_inst *sdi)
devc->cur_samplerate = devc->samplerates[0];
}
if (devc->cur_threshold == 0.0)
devc->cur_threshold = 1.5;
return SR_OK;
}
@ -402,7 +404,7 @@ static int config_get(uint32_t key, GVariant **data,
struct dev_context *devc;
struct sr_usb_dev_inst *usb;
GVariant *range[2];
unsigned int i;
unsigned int i, voltage_range;
char str[128];
(void)cg;
@ -425,14 +427,25 @@ static int config_get(uint32_t key, GVariant **data,
*data = g_variant_new_string(str);
break;
case SR_CONF_VOLTAGE_THRESHOLD:
for (i = 0; i < ARRAY_SIZE(volt_thresholds); i++) {
if (volt_thresholds[i].range != devc->voltage_threshold)
continue;
range[0] = g_variant_new_double(volt_thresholds[i].low);
range[1] = g_variant_new_double(volt_thresholds[i].high);
*data = g_variant_new_tuple(range, 2);
break;
if (!strcmp(devc->profile->model, "DSLogic")) {
voltage_range = 0;
for (i = 0; i < ARRAY_SIZE(dslogic_voltage_thresholds); i++)
if (dslogic_voltage_thresholds[i].low ==
devc->cur_threshold) {
voltage_range = i;
break;
}
range[0] = g_variant_new_double(
dslogic_voltage_thresholds[voltage_range].low);
range[1] = g_variant_new_double(
dslogic_voltage_thresholds[voltage_range].high);
} else {
range[0] = g_variant_new_double(devc->cur_threshold);
range[1] = g_variant_new_double(devc->cur_threshold);
}
*data = g_variant_new_tuple(range, 2);
break;
case SR_CONF_LIMIT_SAMPLES:
*data = g_variant_new_uint64(devc->limit_samples);
@ -525,15 +538,20 @@ static int config_set(uint32_t key, GVariant *data,
break;
case SR_CONF_VOLTAGE_THRESHOLD:
g_variant_get(data, "(dd)", &low, &high);
ret = SR_ERR_ARG;
for (i = 0; (unsigned int)i < ARRAY_SIZE(volt_thresholds); i++) {
if (fabs(volt_thresholds[i].low - low) < 0.1 &&
fabs(volt_thresholds[i].high - high) < 0.1) {
devc->voltage_threshold = volt_thresholds[i].range;
break;
if (!strcmp(devc->profile->model, "DSLogic")) {
for (i = 0; (unsigned int)i <
ARRAY_SIZE(dslogic_voltage_thresholds); i++) {
if (fabs(dslogic_voltage_thresholds[i].low - low) < 0.1 &&
fabs(dslogic_voltage_thresholds[i].high - high) < 0.1) {
devc->cur_threshold =
dslogic_voltage_thresholds[i].low;
break;
}
}
ret = dslogic_fpga_firmware_upload(sdi);
} else {
ret = dslogic_set_voltage_threshold(sdi, (low + high) / 2.0);
}
ret = dslogic_fpga_firmware_upload(sdi);
break;
case SR_CONF_EXTERNAL_CLOCK:
devc->external_clock = g_variant_get_boolean(data);
@ -558,10 +576,11 @@ static int config_set(uint32_t key, GVariant *data,
static int config_list(uint32_t key, GVariant **data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{
struct dev_context *devc;
struct dev_context *devc = NULL;
GVariant *gvar, *range[2];
GVariantBuilder gvb;
unsigned int i;
double v;
(void)cg;
@ -581,15 +600,23 @@ static int config_list(uint32_t key, GVariant **data,
}
break;
case SR_CONF_VOLTAGE_THRESHOLD:
if (!sdi->priv)
return SR_ERR_ARG;
devc = sdi->priv;
if (sdi->priv)
devc = sdi->priv;
g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
for (i = 0; i < ARRAY_SIZE(volt_thresholds); i++) {
range[0] = g_variant_new_double(volt_thresholds[i].low);
range[1] = g_variant_new_double(volt_thresholds[i].high);
gvar = g_variant_new_tuple(range, 2);
g_variant_builder_add_value(&gvb, gvar);
if (devc && !strcmp(devc->profile->model, "DSLogic")) {
for (i = 0; i < ARRAY_SIZE(dslogic_voltage_thresholds); i++) {
range[0] = g_variant_new_double(dslogic_voltage_thresholds[i].low);
range[1] = g_variant_new_double(dslogic_voltage_thresholds[i].high);
gvar = g_variant_new_tuple(range, 2);
g_variant_builder_add_value(&gvb, gvar);
}
} else {
for (v = 0.0; v <= 5.0; v += 0.1) {
range[0] = g_variant_new_double(v);
range[1] = g_variant_new_double(v);
gvar = g_variant_new_tuple(range, 2);
g_variant_builder_add_value(&gvb, gvar);
}
}
*data = g_variant_builder_end(&gvb);
break;
@ -737,15 +764,6 @@ static int trigger_request(const struct sr_dev_inst *sdi)
if ((ret = dslogic_fpga_configure(sdi)) != SR_OK)
return ret;
/* If this is a DSLogic Pro, set the voltage threshold. */
if (!strcmp(devc->profile->model, "DSLogic Pro")){
if (devc->voltage_threshold == DS_VOLTAGE_RANGE_18_33_V) {
dslogic_set_vth(sdi, 1.4);
} else {
dslogic_set_vth(sdi, 3.3);
}
}
if ((ret = dslogic_start_acquisition(sdi)) != SR_OK)
return ret;

View File

@ -36,29 +36,6 @@
#define USB_TIMEOUT (3 * 1000)
SR_PRIV int dslogic_set_vth(const struct sr_dev_inst *sdi, double vth)
{
struct sr_usb_dev_inst *usb;
int ret;
const uint8_t value = (vth / 5.0) * 255;
const uint16_t cmd = value | (DS_ADDR_VTH << 8);
usb = sdi->conn;
/* Send the control command. */
ret = libusb_control_transfer(usb->devhdl,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT,
DS_CMD_WR_REG, 0x0000, 0x0000,
(unsigned char *)&cmd, sizeof(cmd), 3000);
if (ret < 0) {
sr_err("Unable to send VTH command: %s.",
libusb_error_name(ret));
return SR_ERR;
}
return SR_OK;
}
SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi)
{
const char *name = NULL;
@ -78,7 +55,7 @@ SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi)
usb = sdi->conn;
if (!strcmp(devc->profile->model, "DSLogic")) {
if (devc->voltage_threshold == DS_VOLTAGE_RANGE_18_33_V)
if (devc->cur_threshold < 1.40)
name = DSLOGIC_FPGA_FIRMWARE_3V3;
else
name = DSLOGIC_FPGA_FIRMWARE_5V;

View File

@ -71,11 +71,6 @@ enum dslogic_operation_modes {
DS_OP_LOOPBACK_TEST,
};
enum {
DS_VOLTAGE_RANGE_18_33_V, /* 1.8V and 3.3V logic */
DS_VOLTAGE_RANGE_5_V, /* 5V logic */
};
enum {
DS_EDGE_RISING,
DS_EDGE_FALLING,
@ -152,7 +147,6 @@ SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi);
SR_PRIV int dslogic_start_acquisition(const struct sr_dev_inst *sdi);
SR_PRIV int dslogic_stop_acquisition(const struct sr_dev_inst *sdi);
SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi);
SR_PRIV int dslogic_set_vth(const struct sr_dev_inst *sdi, double vth);
SR_PRIV int dslogic_get_number_of_transfers(struct dev_context *devc);
#endif

View File

@ -77,6 +77,30 @@ static int command_get_revid_version(struct sr_dev_inst *sdi, uint8_t *revid)
return SR_OK;
}
SR_PRIV int dslogic_set_voltage_threshold(const struct sr_dev_inst *sdi, double threshold)
{
int ret;
struct dev_context *const devc = sdi->priv;
const struct sr_usb_dev_inst *const usb = sdi->conn;
const uint8_t value = (threshold / 5.0) * 255;
const uint16_t cmd = value | (DS_ADDR_VTH << 8);
/* Send the control command. */
ret = libusb_control_transfer(usb->devhdl,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT,
DS_CMD_WR_REG, 0x0000, 0x0000,
(unsigned char *)&cmd, sizeof(cmd), 3000);
if (ret < 0) {
sr_err("Unable to set voltage-threshold register: %s.",
libusb_error_name(ret));
return SR_ERR;
}
devc->cur_threshold = threshold;
return SR_OK;
}
SR_PRIV int dslogic_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di)
{
libusb_device **devlist;

View File

@ -105,9 +105,10 @@ struct dev_context {
gboolean external_clock;
gboolean continuous_mode;
int clock_edge;
int voltage_threshold;
double cur_threshold;
};
SR_PRIV int dslogic_set_voltage_threshold(const struct sr_dev_inst *sdi, double threshold);
SR_PRIV int dslogic_command_start_acquisition(const struct sr_dev_inst *sdi);
SR_PRIV int dslogic_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di);
SR_PRIV struct dev_context *dslogic_dev_new(void);