hantek-dso: Fix driver/global/channel group config keys.

This was way behind and did not yet support channel groups.
This commit is contained in:
Bert Vermeulen 2014-10-27 17:03:02 +01:00
parent 6fad08e6ab
commit 933defaa03
3 changed files with 279 additions and 225 deletions

View File

@ -47,20 +47,26 @@ static const uint32_t scanopts[] = {
static const uint32_t devopts[] = { static const uint32_t devopts[] = {
SR_CONF_OSCILLOSCOPE, SR_CONF_OSCILLOSCOPE,
SR_CONF_CONTINUOUS, SR_CONF_CONTINUOUS,
SR_CONF_CONN | SR_CONF_GET,
SR_CONF_LIMIT_FRAMES | SR_CONF_SET, SR_CONF_LIMIT_FRAMES | SR_CONF_SET,
SR_CONF_TIMEBASE | SR_CONF_SET | SR_CONF_LIST, };
SR_CONF_BUFFERSIZE | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_TRIGGER_SOURCE | SR_CONF_SET | SR_CONF_LIST, static const uint32_t devopts_global[] = {
SR_CONF_TRIGGER_SLOPE | SR_CONF_SET, SR_CONF_CONN | SR_CONF_GET,
SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_SET, SR_CONF_TIMEBASE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_FILTER | SR_CONF_SET | SR_CONF_LIST, SR_CONF_BUFFERSIZE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_VDIV | SR_CONF_SET | SR_CONF_LIST, SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_COUPLING | SR_CONF_SET | SR_CONF_LIST, SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET,
SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET,
SR_CONF_NUM_TIMEBASE | SR_CONF_GET, SR_CONF_NUM_TIMEBASE | SR_CONF_GET,
SR_CONF_NUM_VDIV | SR_CONF_GET, SR_CONF_NUM_VDIV | SR_CONF_GET,
}; };
static const uint32_t devopts_cg[] = {
SR_CONF_FILTER | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
};
static const char *channel_names[] = { static const char *channel_names[] = {
"CH1", "CH2", "CH1", "CH2",
NULL, NULL,
@ -141,10 +147,9 @@ static const char *trigger_sources[] = {
/* TODO: forced */ /* TODO: forced */
}; };
static const char *filter_targets[] = { static const char *trigger_slopes[] = {
"CH1", "r",
"CH2", "f",
/* TODO: "TRIGGER", */
}; };
static const char *coupling[] = { static const char *coupling[] = {
@ -162,14 +167,12 @@ static struct sr_dev_inst *dso_dev_new(const struct dso_profile *prof)
{ {
struct sr_dev_inst *sdi; struct sr_dev_inst *sdi;
struct sr_channel *ch; struct sr_channel *ch;
struct sr_channel_group *cg;
struct drv_context *drvc; struct drv_context *drvc;
struct dev_context *devc; struct dev_context *devc;
int i; int i;
sdi = sr_dev_inst_new(SR_ST_INITIALIZING, sdi = sr_dev_inst_new(SR_ST_INITIALIZING, prof->vendor, prof->model, NULL);
prof->vendor, prof->model, NULL);
if (!sdi)
return NULL;
sdi->driver = di; sdi->driver = di;
/* /*
@ -177,26 +180,24 @@ static struct sr_dev_inst *dso_dev_new(const struct dso_profile *prof)
* a trigger source internal to the device. * a trigger source internal to the device.
*/ */
for (i = 0; channel_names[i]; i++) { for (i = 0; channel_names[i]; i++) {
if (!(ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE, ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE, channel_names[i]);
channel_names[i])))
return NULL;
sdi->channels = g_slist_append(sdi->channels, ch); sdi->channels = g_slist_append(sdi->channels, ch);
cg = g_malloc0(sizeof(struct sr_channel_group));
cg->name = g_strdup(channel_names[i]);
cg->channels = g_slist_append(cg->channels, ch);
sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
} }
if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { devc = g_malloc0(sizeof(struct dev_context));
sr_err("Device context malloc failed.");
return NULL;
}
devc->profile = prof; devc->profile = prof;
devc->dev_state = IDLE; devc->dev_state = IDLE;
devc->timebase = DEFAULT_TIMEBASE; devc->timebase = DEFAULT_TIMEBASE;
devc->ch1_enabled = TRUE; devc->ch1_enabled = TRUE;
devc->ch2_enabled = TRUE; devc->ch2_enabled = TRUE;
devc->voltage_ch1 = DEFAULT_VOLTAGE; devc->voltage[0] = DEFAULT_VOLTAGE;
devc->voltage_ch2 = DEFAULT_VOLTAGE; devc->voltage[1] = DEFAULT_VOLTAGE;
devc->coupling_ch1 = DEFAULT_COUPLING; devc->coupling[0] = DEFAULT_COUPLING;
devc->coupling_ch2 = DEFAULT_COUPLING; devc->coupling[1] = DEFAULT_COUPLING;
devc->voffset_ch1 = DEFAULT_VERT_OFFSET; devc->voffset_ch1 = DEFAULT_VERT_OFFSET;
devc->voffset_ch2 = DEFAULT_VERT_OFFSET; devc->voffset_ch2 = DEFAULT_VERT_OFFSET;
devc->voffset_trigger = DEFAULT_VERT_TRIGGERPOS; devc->voffset_trigger = DEFAULT_VERT_TRIGGERPOS;
@ -426,31 +427,82 @@ static int cleanup(void)
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi, static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
const struct sr_channel_group *cg) const struct sr_channel_group *cg)
{ {
struct dev_context *devc;
struct sr_usb_dev_inst *usb; struct sr_usb_dev_inst *usb;
char str[128]; char str[128], *s;
const uint64_t *vdiv;
int ch_idx;
(void)cg; (void)cg;
switch (key) { switch (key) {
case SR_CONF_CONN:
if (!sdi || !sdi->conn)
return SR_ERR_ARG;
usb = sdi->conn;
if (usb->address == 255)
/* Device still needs to re-enumerate after firmware
* upload, so we don't know its (future) address. */
return SR_ERR;
snprintf(str, 128, "%d.%d", usb->bus, usb->address);
*data = g_variant_new_string(str);
break;
case SR_CONF_NUM_TIMEBASE: case SR_CONF_NUM_TIMEBASE:
*data = g_variant_new_int32(NUM_TIMEBASE); *data = g_variant_new_int32(NUM_TIMEBASE);
break; break;
case SR_CONF_NUM_VDIV: case SR_CONF_NUM_VDIV:
*data = g_variant_new_int32(NUM_VDIV); *data = g_variant_new_int32(NUM_VDIV);
break; break;
default: }
return SR_ERR_NA;
if (!sdi)
return SR_ERR_ARG;
devc = sdi->priv;
if (!cg) {
switch (key) {
case SR_CONF_CONN:
if (!sdi->conn)
return SR_ERR_ARG;
usb = sdi->conn;
if (usb->address == 255)
/* Device still needs to re-enumerate after firmware
* upload, so we don't know its (future) address. */
return SR_ERR;
snprintf(str, 128, "%d.%d", usb->bus, usb->address);
*data = g_variant_new_string(str);
break;
case SR_CONF_TIMEBASE:
*data = g_variant_new("(tt)", timebases[devc->timebase][0],
timebases[devc->timebase][1]);
break;
case SR_CONF_BUFFERSIZE:
*data = g_variant_new_uint64(devc->framesize);
break;
case SR_CONF_TRIGGER_SOURCE:
*data = g_variant_new_string(devc->triggersource);
break;
case SR_CONF_TRIGGER_SLOPE:
if (devc->triggerslope == SLOPE_POSITIVE)
s = "r";
else
s = "f";
*data = g_variant_new_string(s);
break;
case SR_CONF_HORIZ_TRIGGERPOS:
*data = g_variant_new_double(devc->triggerposition);
break;
default:
return SR_ERR_NA;
}
} else {
if (sdi->channel_groups->data == cg)
ch_idx = 0;
else if (sdi->channel_groups->next->data == cg)
ch_idx = 1;
else
return SR_ERR_ARG;
switch(key) {
case SR_CONF_FILTER:
*data = g_variant_new_boolean(devc->filter[ch_idx]);
break;
case SR_CONF_VDIV:
vdiv = vdivs[devc->voltage[ch_idx]];
*data = g_variant_new("(tt)", vdiv[0], vdiv[1]);
break;
case SR_CONF_COUPLING:
*data = g_variant_new_string(coupling[devc->coupling[ch_idx]]);
break;
}
} }
return SR_OK; return SR_OK;
@ -462,126 +514,115 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd
struct dev_context *devc; struct dev_context *devc;
double tmp_double; double tmp_double;
uint64_t tmp_u64, p, q; uint64_t tmp_u64, p, q;
int tmp_int, ret; int tmp_int, ch_idx, ret;
unsigned int i; unsigned int i;
const char *tmp_str; const char *tmp_str;
char **targets;
(void)cg;
if (sdi->status != SR_ST_ACTIVE) if (sdi->status != SR_ST_ACTIVE)
return SR_ERR_DEV_CLOSED; return SR_ERR_DEV_CLOSED;
ret = SR_OK; ret = SR_OK;
devc = sdi->priv; devc = sdi->priv;
switch (key) { if (!cg) {
case SR_CONF_LIMIT_FRAMES: switch (key) {
devc->limit_frames = g_variant_get_uint64(data); case SR_CONF_LIMIT_FRAMES:
break; devc->limit_frames = g_variant_get_uint64(data);
case SR_CONF_TRIGGER_SLOPE: break;
tmp_str = g_variant_get_string(data, NULL); case SR_CONF_TRIGGER_SLOPE:
if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r')) tmp_str = g_variant_get_string(data, NULL);
return SR_ERR_ARG; if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r'))
devc->triggerslope = (tmp_str[0] == 'r') return SR_ERR_ARG;
? SLOPE_POSITIVE : SLOPE_NEGATIVE; devc->triggerslope = (tmp_str[0] == 'r')
break; ? SLOPE_POSITIVE : SLOPE_NEGATIVE;
case SR_CONF_HORIZ_TRIGGERPOS: break;
tmp_double = g_variant_get_double(data); case SR_CONF_HORIZ_TRIGGERPOS:
if (tmp_double < 0.0 || tmp_double > 1.0) { tmp_double = g_variant_get_double(data);
sr_err("Trigger position should be between 0.0 and 1.0."); if (tmp_double < 0.0 || tmp_double > 1.0) {
ret = SR_ERR_ARG; sr_err("Trigger position should be between 0.0 and 1.0.");
} else
devc->triggerposition = tmp_double;
break;
case SR_CONF_BUFFERSIZE:
tmp_u64 = g_variant_get_uint64(data);
for (i = 0; i < 2; i++) {
if (devc->profile->buffersizes[i] == tmp_u64) {
devc->framesize = tmp_u64;
break;
}
}
if (i == 2)
ret = SR_ERR_ARG;
break;
case SR_CONF_TIMEBASE:
g_variant_get(data, "(tt)", &p, &q);
tmp_int = -1;
for (i = 0; i < ARRAY_SIZE(timebases); i++) {
if (timebases[i][0] == p && timebases[i][1] == q) {
tmp_int = i;
break;
}
}
if (tmp_int >= 0)
devc->timebase = tmp_int;
else
ret = SR_ERR_ARG;
break;
case SR_CONF_TRIGGER_SOURCE:
tmp_str = g_variant_get_string(data, NULL);
for (i = 0; trigger_sources[i]; i++) {
if (!strcmp(tmp_str, trigger_sources[i])) {
devc->triggersource = g_strdup(tmp_str);
break;
}
}
if (trigger_sources[i] == 0)
ret = SR_ERR_ARG;
break;
case SR_CONF_FILTER:
tmp_str = g_variant_get_string(data, NULL);
devc->filter_ch1 = devc->filter_ch2 = devc->filter_trigger = 0;
targets = g_strsplit(tmp_str, ",", 0);
for (i = 0; targets[i]; i++) {
if (targets[i] == '\0')
/* Empty filter string can be used to clear them all. */
;
else if (!strcmp(targets[i], "CH1"))
devc->filter_ch1 = TRUE;
else if (!strcmp(targets[i], "CH2"))
devc->filter_ch2 = TRUE;
else if (!strcmp(targets[i], "TRIGGER"))
devc->filter_trigger = TRUE;
else {
sr_err("Invalid filter target %s.", targets[i]);
ret = SR_ERR_ARG; ret = SR_ERR_ARG;
} else
devc->triggerposition = tmp_double;
break;
case SR_CONF_BUFFERSIZE:
tmp_u64 = g_variant_get_uint64(data);
for (i = 0; i < 2; i++) {
if (devc->profile->buffersizes[i] == tmp_u64) {
devc->framesize = tmp_u64;
break;
}
} }
} if (i == 2)
g_strfreev(targets); ret = SR_ERR_ARG;
break; break;
case SR_CONF_VDIV: case SR_CONF_TIMEBASE:
/* TODO: Not supporting vdiv per channel yet. */ g_variant_get(data, "(tt)", &p, &q);
g_variant_get(data, "(tt)", &p, &q); tmp_int = -1;
tmp_int = -1; for (i = 0; i < ARRAY_SIZE(timebases); i++) {
for (i = 0; i < ARRAY_SIZE(vdivs); i++) { if (timebases[i][0] == p && timebases[i][1] == q) {
if (vdivs[i][0] == p && vdivs[i][1] == q) { tmp_int = i;
tmp_int = i; break;
break; }
} }
} if (tmp_int >= 0)
if (tmp_int >= 0) { devc->timebase = tmp_int;
devc->voltage_ch1 = tmp_int; else
devc->voltage_ch2 = tmp_int; ret = SR_ERR_ARG;
} else break;
ret = SR_ERR_ARG; case SR_CONF_TRIGGER_SOURCE:
break; tmp_str = g_variant_get_string(data, NULL);
case SR_CONF_COUPLING: for (i = 0; trigger_sources[i]; i++) {
tmp_str = g_variant_get_string(data, NULL); if (!strcmp(tmp_str, trigger_sources[i])) {
/* TODO: Not supporting coupling per channel yet. */ devc->triggersource = g_strdup(tmp_str);
for (i = 0; coupling[i]; i++) { break;
if (!strcmp(tmp_str, coupling[i])) { }
devc->coupling_ch1 = i;
devc->coupling_ch2 = i;
break;
} }
if (trigger_sources[i] == 0)
ret = SR_ERR_ARG;
break;
default:
ret = SR_ERR_NA;
break;
}
} else {
if (sdi->channel_groups->data == cg)
ch_idx = 0;
else if (sdi->channel_groups->next->data == cg)
ch_idx = 1;
else
return SR_ERR_ARG;
switch (key) {
case SR_CONF_FILTER:
devc->filter[ch_idx] = g_variant_get_boolean(data);
break;
case SR_CONF_VDIV:
g_variant_get(data, "(tt)", &p, &q);
tmp_int = -1;
for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
if (vdivs[i][0] == p && vdivs[i][1] == q) {
tmp_int = i;
break;
}
}
if (tmp_int >= 0) {
devc->voltage[ch_idx] = tmp_int;
} else
ret = SR_ERR_ARG;
break;
case SR_CONF_COUPLING:
tmp_str = g_variant_get_string(data, NULL);
for (i = 0; coupling[i]; i++) {
if (!strcmp(tmp_str, coupling[i])) {
devc->coupling[ch_idx] = i;
break;
}
}
if (coupling[i] == 0)
ret = SR_ERR_ARG;
break;
default:
ret = SR_ERR_NA;
break;
} }
if (coupling[i] == 0)
ret = SR_ERR_ARG;
break;
default:
ret = SR_ERR_NA;
break;
} }
return ret; return ret;
@ -595,57 +636,75 @@ static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *
GVariantBuilder gvb; GVariantBuilder gvb;
unsigned int i; unsigned int i;
(void)cg; if (key == SR_CONF_SCAN_OPTIONS) {
switch (key) {
case SR_CONF_SCAN_OPTIONS:
*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t)); scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
break; return SR_OK;
case SR_CONF_DEVICE_OPTIONS: } else if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
devopts, ARRAY_SIZE(devopts), sizeof(uint32_t)); devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
break; return SR_OK;
case SR_CONF_BUFFERSIZE: }
if (!sdi)
return SR_ERR_ARG; if (!sdi)
devc = sdi->priv; return SR_ERR_ARG;
*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT64,
devc->profile->buffersizes, 2, sizeof(uint64_t)); if (!cg) {
break; switch (key) {
case SR_CONF_COUPLING: case SR_CONF_DEVICE_OPTIONS:
*data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling)); *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
break; devopts_global, ARRAY_SIZE(devopts_global), sizeof(uint32_t));
case SR_CONF_VDIV: break;
g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY); case SR_CONF_BUFFERSIZE:
for (i = 0; i < ARRAY_SIZE(vdivs); i++) { if (!sdi)
rational[0] = g_variant_new_uint64(vdivs[i][0]); return SR_ERR_ARG;
rational[1] = g_variant_new_uint64(vdivs[i][1]); devc = sdi->priv;
tuple = g_variant_new_tuple(rational, 2); *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT64,
g_variant_builder_add_value(&gvb, tuple); devc->profile->buffersizes, 2, sizeof(uint64_t));
break;
case SR_CONF_TIMEBASE:
g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
for (i = 0; i < ARRAY_SIZE(timebases); i++) {
rational[0] = g_variant_new_uint64(timebases[i][0]);
rational[1] = g_variant_new_uint64(timebases[i][1]);
tuple = g_variant_new_tuple(rational, 2);
g_variant_builder_add_value(&gvb, tuple);
}
*data = g_variant_builder_end(&gvb);
break;
case SR_CONF_TRIGGER_SOURCE:
*data = g_variant_new_strv(trigger_sources,
ARRAY_SIZE(trigger_sources));
break;
case SR_CONF_TRIGGER_SLOPE:
*data = g_variant_new_strv(trigger_slopes,
ARRAY_SIZE(trigger_slopes));
break;
default:
return SR_ERR_NA;
} }
*data = g_variant_builder_end(&gvb); } else {
break; switch (key) {
case SR_CONF_FILTER: case SR_CONF_DEVICE_OPTIONS:
*data = g_variant_new_strv(filter_targets, *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
ARRAY_SIZE(filter_targets)); devopts_cg, ARRAY_SIZE(devopts_cg), sizeof(uint32_t));
break; break;
case SR_CONF_TIMEBASE: case SR_CONF_COUPLING:
g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY); *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
for (i = 0; i < ARRAY_SIZE(timebases); i++) { break;
rational[0] = g_variant_new_uint64(timebases[i][0]); case SR_CONF_VDIV:
rational[1] = g_variant_new_uint64(timebases[i][1]); g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
tuple = g_variant_new_tuple(rational, 2); for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
g_variant_builder_add_value(&gvb, tuple); rational[0] = g_variant_new_uint64(vdivs[i][0]);
rational[1] = g_variant_new_uint64(vdivs[i][1]);
tuple = g_variant_new_tuple(rational, 2);
g_variant_builder_add_value(&gvb, tuple);
}
*data = g_variant_builder_end(&gvb);
break;
default:
return SR_ERR_NA;
} }
*data = g_variant_builder_end(&gvb);
break;
case SR_CONF_TRIGGER_SOURCE:
*data = g_variant_new_strv(trigger_sources,
ARRAY_SIZE(trigger_sources));
break;
default:
return SR_ERR_NA;
} }
return SR_OK; return SR_OK;
@ -688,14 +747,14 @@ static void send_chunk(struct sr_dev_inst *sdi, unsigned char *buf,
*/ */
/* TODO: Support for DSO-5xxx series 9-bit samples. */ /* TODO: Support for DSO-5xxx series 9-bit samples. */
if (devc->ch1_enabled) { if (devc->ch1_enabled) {
range = ((float)vdivs[devc->voltage_ch1][0] / vdivs[devc->voltage_ch1][1]) * 8; range = ((float)vdivs[devc->voltage[0]][0] / vdivs[devc->voltage[0]][1]) * 8;
ch1 = range / 255 * *(buf + i * 2 + 1); ch1 = range / 255 * *(buf + i * 2 + 1);
/* Value is centered around 0V. */ /* Value is centered around 0V. */
ch1 -= range / 2; ch1 -= range / 2;
analog.data[data_offset++] = ch1; analog.data[data_offset++] = ch1;
} }
if (devc->ch2_enabled) { if (devc->ch2_enabled) {
range = ((float)vdivs[devc->voltage_ch2][0] / vdivs[devc->voltage_ch2][1]) * 8; range = ((float)vdivs[devc->voltage[1]][0] / vdivs[devc->voltage[1]][1]) * 8;
ch2 = range / 255 * *(buf + i * 2); ch2 = range / 255 * *(buf + i * 2);
ch2 -= range / 2; ch2 -= range / 2;
analog.data[data_offset++] = ch2; analog.data[data_offset++] = ch2;

View File

@ -383,19 +383,18 @@ static int dso_set_filters(const struct sr_dev_inst *sdi)
memset(cmdstring, 0, sizeof(cmdstring)); memset(cmdstring, 0, sizeof(cmdstring));
cmdstring[0] = CMD_SET_FILTERS; cmdstring[0] = CMD_SET_FILTERS;
cmdstring[1] = 0x0f; cmdstring[1] = 0x0f;
if (devc->filter_ch1) { if (devc->filter[0]) {
sr_dbg("Turning on CH1 filter."); sr_dbg("Turning on CH1 filter.");
cmdstring[2] |= 0x80; cmdstring[2] |= 0x80;
} }
if (devc->filter_ch2) { if (devc->filter[1]) {
sr_dbg("Turning on CH2 filter."); sr_dbg("Turning on CH2 filter.");
cmdstring[2] |= 0x40; cmdstring[2] |= 0x40;
} }
if (devc->filter_trigger) { /*
/* TODO: supported on the DSO-2090? */ * Not supported: filtering on the trigger
sr_dbg("Turning on trigger filter."); * cmdstring[2] |= 0x20;
cmdstring[2] |= 0x20; */
}
if (send_begin(sdi) != SR_OK) if (send_begin(sdi) != SR_OK)
return SR_ERR; return SR_ERR;
@ -428,8 +427,8 @@ static int dso_set_voltage(const struct sr_dev_inst *sdi)
cmdstring[2] = 0x30; cmdstring[2] = 0x30;
/* CH1 volts/div is encoded in bits 0-1 */ /* CH1 volts/div is encoded in bits 0-1 */
sr_dbg("CH1 vdiv index: %d.", devc->voltage_ch1); sr_dbg("CH1 vdiv index: %d.", devc->voltage[0]);
switch (devc->voltage_ch1) { switch (devc->voltage[0]) {
case VDIV_1V: case VDIV_1V:
case VDIV_100MV: case VDIV_100MV:
case VDIV_10MV: case VDIV_10MV:
@ -448,8 +447,8 @@ static int dso_set_voltage(const struct sr_dev_inst *sdi)
} }
/* CH2 volts/div is encoded in bits 2-3 */ /* CH2 volts/div is encoded in bits 2-3 */
sr_dbg("CH2 vdiv index: %d.", devc->voltage_ch2); sr_dbg("CH2 vdiv index: %d.", devc->voltage[1]);
switch (devc->voltage_ch2) { switch (devc->voltage[1]) {
case VDIV_1V: case VDIV_1V:
case VDIV_100MV: case VDIV_100MV:
case VDIV_10MV: case VDIV_10MV:
@ -494,24 +493,24 @@ static int dso_set_relays(const struct sr_dev_inst *sdi)
devc = sdi->priv; devc = sdi->priv;
usb = sdi->conn; usb = sdi->conn;
if (devc->voltage_ch1 < VDIV_1V) if (devc->voltage[0] < VDIV_1V)
relays[1] = ~relays[1]; relays[1] = ~relays[1];
if (devc->voltage_ch1 < VDIV_100MV) if (devc->voltage[0] < VDIV_100MV)
relays[2] = ~relays[2]; relays[2] = ~relays[2];
sr_dbg("CH1 coupling: %d.", devc->coupling_ch1); sr_dbg("CH1 coupling: %d.", devc->coupling[0]);
if (devc->coupling_ch1 != COUPLING_AC) if (devc->coupling[0] != COUPLING_AC)
relays[3] = ~relays[3]; relays[3] = ~relays[3];
if (devc->voltage_ch2 < VDIV_1V) if (devc->voltage[1] < VDIV_1V)
relays[4] = ~relays[4]; relays[4] = ~relays[4];
if (devc->voltage_ch2 < VDIV_100MV) if (devc->voltage[1] < VDIV_100MV)
relays[5] = ~relays[5]; relays[5] = ~relays[5];
sr_dbg("CH2 coupling: %d.", devc->coupling_ch1); sr_dbg("CH2 coupling: %d.", devc->coupling[1]);
if (devc->coupling_ch2 != COUPLING_AC) if (devc->coupling[1] != COUPLING_AC)
relays[6] = ~relays[6]; relays[6] = ~relays[6];
if (!strcmp(devc->triggersource, "EXT")) if (!strcmp(devc->triggersource, "EXT"))
@ -552,7 +551,7 @@ static int dso_set_voffsets(const struct sr_dev_inst *sdi)
memset(offsets, 0, sizeof(offsets)); memset(offsets, 0, sizeof(offsets));
/* Channel 1 */ /* Channel 1 */
ch_levels = devc->channel_levels[0][devc->voltage_ch1]; ch_levels = devc->channel_levels[0][devc->voltage[0]];
offset = (ch_levels[1] - ch_levels[0]) * devc->voffset_ch1 + ch_levels[0]; offset = (ch_levels[1] - ch_levels[0]) * devc->voffset_ch1 + ch_levels[0];
offsets[0] = (offset >> 8) | 0x20; offsets[0] = (offset >> 8) | 0x20;
offsets[1] = offset & 0xff; offsets[1] = offset & 0xff;
@ -560,7 +559,7 @@ static int dso_set_voffsets(const struct sr_dev_inst *sdi)
offsets[0], offsets[1]); offsets[0], offsets[1]);
/* Channel 2 */ /* Channel 2 */
ch_levels = devc->channel_levels[1][devc->voltage_ch2]; ch_levels = devc->channel_levels[1][devc->voltage[1]];
offset = (ch_levels[1] - ch_levels[0]) * devc->voffset_ch2 + ch_levels[0]; offset = (ch_levels[1] - ch_levels[0]) * devc->voffset_ch2 + ch_levels[0];
offsets[2] = (offset >> 8) | 0x20; offsets[2] = (offset >> 8) | 0x20;
offsets[3] = offset & 0xff; offsets[3] = offset & 0xff;

View File

@ -180,19 +180,15 @@ struct dev_context {
int timebase; int timebase;
gboolean ch1_enabled; gboolean ch1_enabled;
gboolean ch2_enabled; gboolean ch2_enabled;
int voltage_ch1; int voltage[2];
int voltage_ch2; int coupling[2];
int coupling_ch1;
int coupling_ch2;
// voltage offset (vertical position) // voltage offset (vertical position)
float voffset_ch1; float voffset_ch1;
float voffset_ch2; float voffset_ch2;
float voffset_trigger; float voffset_trigger;
uint16_t channel_levels[2][9][2]; uint16_t channel_levels[2][9][2];
unsigned int framesize; unsigned int framesize;
gboolean filter_ch1; gboolean filter[2];
gboolean filter_ch2;
gboolean filter_trigger;
int triggerslope; int triggerslope;
char *triggersource; char *triggersource;
float triggerposition; float triggerposition;