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

View File

@ -36,29 +36,6 @@
#define USB_TIMEOUT (3 * 1000) #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) SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi)
{ {
const char *name = NULL; const char *name = NULL;
@ -78,7 +55,7 @@ SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi)
usb = sdi->conn; usb = sdi->conn;
if (!strcmp(devc->profile->model, "DSLogic")) { 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; name = DSLOGIC_FPGA_FIRMWARE_3V3;
else else
name = DSLOGIC_FPGA_FIRMWARE_5V; name = DSLOGIC_FPGA_FIRMWARE_5V;

View File

@ -71,11 +71,6 @@ enum dslogic_operation_modes {
DS_OP_LOOPBACK_TEST, 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 { enum {
DS_EDGE_RISING, DS_EDGE_RISING,
DS_EDGE_FALLING, 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_start_acquisition(const struct sr_dev_inst *sdi);
SR_PRIV int dslogic_stop_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_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); SR_PRIV int dslogic_get_number_of_transfers(struct dev_context *devc);
#endif #endif

View File

@ -77,6 +77,30 @@ static int command_get_revid_version(struct sr_dev_inst *sdi, uint8_t *revid)
return SR_OK; 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) SR_PRIV int dslogic_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di)
{ {
libusb_device **devlist; libusb_device **devlist;

View File

@ -105,9 +105,10 @@ struct dev_context {
gboolean external_clock; gboolean external_clock;
gboolean continuous_mode; gboolean continuous_mode;
int clock_edge; 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_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 int dslogic_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di);
SR_PRIV struct dev_context *dslogic_dev_new(void); SR_PRIV struct dev_context *dslogic_dev_new(void);