rigol-ds: Overhaul vendor/series/model info and protocol variants.

This commit is contained in:
Martin Ling 2014-01-22 04:08:00 +00:00 committed by Bert Vermeulen
parent e086b750fa
commit 569d4dbd3e
3 changed files with 177 additions and 150 deletions

View File

@ -156,47 +156,74 @@ static const char *data_sources[] = {
"Segmented", "Segmented",
}; };
/* enum vendor {
* name, series, protocol flavor, min timebase, max timebase, min vdiv, RIGOL,
* digital channels, number of horizontal divs AGILENT,
*/ };
#define RIGOL "Rigol Technologies" enum series {
#define AGILENT "Agilent Technologies" VS5000,
#define RIGOL_SHORT "Rigol" DS1000,
#define AGILENT_SHORT "Agilent" DS2000,
DS2000A,
DSO1000,
};
/* short name, full name */
static const struct rigol_ds_vendor supported_vendors[] = {
[RIGOL] = {"Rigol", "Rigol Technologies"},
[AGILENT] = {"Agilent", "Rigol Technologies"},
};
#define VENDOR(x) &supported_vendors[x]
/* vendor, series, protocol, max timebase, min vdiv, number of horizontal divs,
* live waveform samples, memory buffer samples */
static const struct rigol_ds_series supported_series[] = {
[VS5000] = {VENDOR(RIGOL), "VS5000", PROTOCOL_V1, FORMAT_RAW,
{50, 1}, {2, 1000}, 14, 2048, 0},
[DS1000] = {VENDOR(RIGOL), "DS1000", PROTOCOL_V2, FORMAT_IEEE488_2,
{50, 1}, {2, 1000}, 12, 600, 1048576},
[DS2000] = {VENDOR(RIGOL), "DS2000", PROTOCOL_V3, FORMAT_IEEE488_2,
{500, 1}, {2, 1000}, 14, 1400, 14000},
[DS2000A] = {VENDOR(RIGOL), "DS2000A", PROTOCOL_V3, FORMAT_IEEE488_2,
{1000, 1}, {500, 1000000}, 14, 1400, 14000},
[DSO1000] = {VENDOR(AGILENT), "DSO1000", PROTOCOL_V3, FORMAT_IEEE488_2,
{50, 1}, {2, 1000}, 12, 600, 20480},
};
#define SERIES(x) &supported_series[x]
/* series, model, min timebase, analog channels, digital */
static const struct rigol_ds_model supported_models[] = { static const struct rigol_ds_model supported_models[] = {
{RIGOL, "DS1052E", RIGOL_DS1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12}, {SERIES(VS5000), "VS5022", {20, 1000000000}, 2, false},
{RIGOL, "DS1102E", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12}, {SERIES(VS5000), "VS5042", {10, 1000000000}, 2, false},
{RIGOL, "DS1152E", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12}, {SERIES(VS5000), "VS5062", {5, 1000000000}, 2, false},
{RIGOL, "DS1052D", RIGOL_DS1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12}, {SERIES(VS5000), "VS5102", {2, 1000000000}, 2, false},
{RIGOL, "DS1102D", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12}, {SERIES(VS5000), "VS5202", {2, 1000000000}, 2, false},
{RIGOL, "DS1152D", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12}, {SERIES(VS5000), "VS5022D", {20, 1000000000}, 2, true},
{RIGOL, "DS2072", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14}, {SERIES(VS5000), "VS5042D", {10, 1000000000}, 2, true},
{RIGOL, "DS2102", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14}, {SERIES(VS5000), "VS5062D", {5, 1000000000}, 2, true},
{RIGOL, "DS2202", RIGOL_DS2000, PROTOCOL_IEEE488_2, {2, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14}, {SERIES(VS5000), "VS5102D", {2, 1000000000}, 2, true},
{RIGOL, "DS2302", RIGOL_DS2000, PROTOCOL_IEEE488_2, {1, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14}, {SERIES(VS5000), "VS5202D", {2, 1000000000}, 2, true},
{RIGOL, "DS2072A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14}, {SERIES(DS1000), "DS1052E", {5, 1000000000}, 2, false},
{RIGOL, "DS2102A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14}, {SERIES(DS1000), "DS1102E", {2, 1000000000}, 2, false},
{RIGOL, "DS2202A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {2, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14}, {SERIES(DS1000), "DS1152E", {2, 1000000000}, 2, false},
{RIGOL, "DS2302A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {1, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14}, {SERIES(DS1000), "DS1052D", {5, 1000000000}, 2, true},
{RIGOL, "VS5022", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14}, {SERIES(DS1000), "DS1102D", {2, 1000000000}, 2, true},
{RIGOL, "VS5022D", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14}, {SERIES(DS1000), "DS1152D", {2, 1000000000}, 2, true},
{RIGOL, "VS5042", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14}, {SERIES(DS2000), "DS2072", {5, 1000000000}, 2, false},
{RIGOL, "VS5042D", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14}, {SERIES(DS2000), "DS2102", {5, 1000000000}, 2, false},
{RIGOL, "VS5062", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14}, {SERIES(DS2000), "DS2202", {2, 1000000000}, 2, false},
{RIGOL, "VS5062D", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14}, {SERIES(DS2000), "DS2302", {1, 1000000000}, 2, false},
{RIGOL, "VS5102", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14}, {SERIES(DS2000A), "DS2072A", {5, 1000000000}, 2, false},
{RIGOL, "VS5102D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14}, {SERIES(DS2000A), "DS2102A", {5, 1000000000}, 2, false},
{RIGOL, "VS5202", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14}, {SERIES(DS2000A), "DS2202A", {2, 1000000000}, 2, false},
{RIGOL, "VS5202D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14}, {SERIES(DS2000A), "DS2302A", {1, 1000000000}, 2, false},
{AGILENT, "DSO1002A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12}, {SERIES(DSO1000), "DSO1002A", {5, 1000000000}, 2, false},
{AGILENT, "DSO1004A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12}, {SERIES(DSO1000), "DSO1004A", {5, 1000000000}, 4, false},
{AGILENT, "DSO1012A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12}, {SERIES(DSO1000), "DSO1012A", {2, 1000000000}, 2, false},
{AGILENT, "DSO1014A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12}, {SERIES(DSO1000), "DSO1014A", {2, 1000000000}, 4, false},
{AGILENT, "DSO1022A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12}, {SERIES(DSO1000), "DSO1022A", {2, 1000000000}, 2, false},
{AGILENT, "DSO1024A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12}, {SERIES(DSO1000), "DSO1024A", {2, 1000000000}, 4, false},
}; };
SR_PRIV struct sr_dev_driver rigol_ds_driver_info; SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
@ -238,7 +265,7 @@ static int probe_port(const char *resource, const char *serialcomm, GSList **dev
long n[3]; long n[3];
unsigned int i; unsigned int i;
const struct rigol_ds_model *model = NULL; const struct rigol_ds_model *model = NULL;
gchar *channel_name, *vendor, **version; gchar *channel_name, **version;
*devices = NULL; *devices = NULL;
@ -259,21 +286,17 @@ static int probe_port(const char *resource, const char *serialcomm, GSList **dev
} }
for (i = 0; i < ARRAY_SIZE(supported_models); i++) { for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
if (!strcasecmp(hw_info->manufacturer, supported_models[i].vendor) && if (!strcasecmp(hw_info->manufacturer,
supported_models[i].series->vendor->full_name) &&
!strcmp(hw_info->model, supported_models[i].name)) { !strcmp(hw_info->model, supported_models[i].name)) {
model = &supported_models[i]; model = &supported_models[i];
break; break;
} }
} }
if (!strcmp(hw_info->manufacturer, RIGOL))
vendor = RIGOL_SHORT;
else if (!strcmp(hw_info->manufacturer, AGILENT))
vendor = AGILENT_SHORT;
else
vendor = hw_info->manufacturer;
if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
vendor, hw_info->model, model->series->vendor->name,
model->name,
hw_info->firmware_version))) { hw_info->firmware_version))) {
sr_scpi_hw_info_free(hw_info); sr_scpi_hw_info_free(hw_info);
sr_scpi_close(scpi); sr_scpi_close(scpi);
@ -293,11 +316,10 @@ static int probe_port(const char *resource, const char *serialcomm, GSList **dev
devc->limit_frames = 0; devc->limit_frames = 0;
devc->model = model; devc->model = model;
devc->protocol = model->protocol; devc->format = model->series->format;
/* DS1000 models with firmware before 0.2.4 used the old /* DS1000 models with firmware before 0.2.4 used the old data format. */
* legacy protocol. */ if (model->series == SERIES(DS1000)) {
if (model->series == RIGOL_DS1000) {
version = g_strsplit(hw_info->firmware_version, ".", 0); version = g_strsplit(hw_info->firmware_version, ".", 0);
do { do {
if (!version[0] || !version[1] || !version[2]) if (!version[0] || !version[1] || !version[2])
@ -314,8 +336,8 @@ static int probe_port(const char *resource, const char *serialcomm, GSList **dev
break; break;
if (n[1] == 2 && n[2] > 3) if (n[1] == 2 && n[2] > 3)
break; break;
sr_dbg("Found DS1000 firmware < 0.2.4, using old protocol."); sr_dbg("Found DS1000 firmware < 0.2.4, using raw data format.");
devc->protocol = PROTOCOL_LEGACY; devc->format = FORMAT_RAW;
} while(0); } while(0);
g_strfreev(version); g_strfreev(version);
} }
@ -353,12 +375,12 @@ static int probe_port(const char *resource, const char *serialcomm, GSList **dev
for (i = 0; i < NUM_TIMEBASE; i++) { for (i = 0; i < NUM_TIMEBASE; i++) {
if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2]))) if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
devc->timebases = &timebases[i]; devc->timebases = &timebases[i];
if (!memcmp(&devc->model->max_timebase, &timebases[i], sizeof(uint64_t[2]))) if (!memcmp(&devc->model->series->max_timebase, &timebases[i], sizeof(uint64_t[2])))
devc->num_timebases = &timebases[i] - devc->timebases + 1; devc->num_timebases = &timebases[i] - devc->timebases + 1;
} }
for (i = 0; i < NUM_VDIV; i++) for (i = 0; i < NUM_VDIV; i++)
if (!memcmp(&devc->model->min_vdiv, &vdivs[i], sizeof(uint64_t[2]))) if (!memcmp(&devc->model->series->min_vdiv, &vdivs[i], sizeof(uint64_t[2])))
devc->vdivs = &vdivs[i]; devc->vdivs = &vdivs[i];
if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE))) if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
@ -463,7 +485,7 @@ static int dev_close(struct sr_dev_inst *sdi)
scpi = sdi->conn; scpi = sdi->conn;
devc = sdi->priv; devc = sdi->priv;
if (devc->model->series != RIGOL_VS5000) if (devc->model->series->protocol >= PROTOCOL_V2)
rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE"); rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
if (scpi) { if (scpi) {
@ -487,28 +509,19 @@ static int analog_frame_size(const struct sr_dev_inst *sdi)
int analog_probes = 0; int analog_probes = 0;
GSList *l; GSList *l;
switch (devc->model->series) { for (l = sdi->probes; l; l = l->next) {
case RIGOL_VS5000: probe = l->data;
return VS5000_ANALOG_LIVE_WAVEFORM_SIZE; if (probe->type == SR_PROBE_ANALOG && probe->enabled)
case RIGOL_DS1000: analog_probes++;
return DS1000_ANALOG_LIVE_WAVEFORM_SIZE; }
switch (devc->data_source) {
case DATA_SOURCE_LIVE:
return devc->model->series->live_samples;
case DATA_SOURCE_MEMORY:
return devc->model->series->buffer_samples / analog_probes;
default: default:
for (l = sdi->probes; l; l = l->next) { return 0;
probe = l->data;
if (probe->type == SR_PROBE_ANALOG && probe->enabled)
analog_probes++;
}
if (devc->data_source == DATA_SOURCE_MEMORY) {
if (analog_probes == 1)
return DS2000_ANALOG_MEM_WAVEFORM_SIZE_1C;
else
return DS2000_ANALOG_MEM_WAVEFORM_SIZE_2C;
} else {
if (devc->model->series == AGILENT_DSO1000)
return DSO1000_ANALOG_LIVE_WAVEFORM_SIZE;
else
return DS2000_ANALOG_LIVE_WAVEFORM_SIZE;
}
} }
} }
@ -516,11 +529,11 @@ static int digital_frame_size(const struct sr_dev_inst *sdi)
{ {
struct dev_context *devc = sdi->priv; struct dev_context *devc = sdi->priv;
switch (devc->model->series) { switch (devc->data_source) {
case RIGOL_VS5000: case DATA_SOURCE_LIVE:
return VS5000_DIGITAL_WAVEFORM_SIZE; return devc->model->series->live_samples * 2;
case RIGOL_DS1000: case DATA_SOURCE_MEMORY:
return DS1000_DIGITAL_WAVEFORM_SIZE; return devc->model->series->buffer_samples * 2;
default: default:
return 0; return 0;
} }
@ -560,7 +573,7 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
switch (id) { switch (id) {
case SR_CONF_NUM_TIMEBASE: case SR_CONF_NUM_TIMEBASE:
*data = g_variant_new_int32(devc->model->num_horizontal_divs); *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
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);
@ -575,7 +588,7 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
case SR_CONF_SAMPLERATE: case SR_CONF_SAMPLERATE:
if (devc->data_source == DATA_SOURCE_LIVE) { if (devc->data_source == DATA_SOURCE_LIVE) {
samplerate = analog_frame_size(sdi) / samplerate = analog_frame_size(sdi) /
(devc->timebase * devc->model->num_horizontal_divs); (devc->timebase * devc->model->series->num_horizontal_divs);
*data = g_variant_new_uint64(samplerate); *data = g_variant_new_uint64(samplerate);
} else { } else {
return SR_ERR_NA; return SR_ERR_NA;
@ -768,9 +781,10 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
tmp_str = g_variant_get_string(data, NULL); tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "Live")) if (!strcmp(tmp_str, "Live"))
devc->data_source = DATA_SOURCE_LIVE; devc->data_source = DATA_SOURCE_LIVE;
else if (!strcmp(tmp_str, "Memory")) else if (devc->model->series->protocol >= PROTOCOL_V2
&& !strcmp(tmp_str, "Memory"))
devc->data_source = DATA_SOURCE_MEMORY; devc->data_source = DATA_SOURCE_MEMORY;
else if (devc->model->series >= RIGOL_DS1000Z else if (devc->model->series->protocol >= PROTOCOL_V3
&& !strcmp(tmp_str, "Segmented")) && !strcmp(tmp_str, "Segmented"))
devc->data_source = DATA_SOURCE_SEGMENTED; devc->data_source = DATA_SOURCE_SEGMENTED;
else else
@ -889,11 +903,17 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
if (!devc) if (!devc)
/* Can't know this until we have the exact model. */ /* Can't know this until we have the exact model. */
return SR_ERR_ARG; return SR_ERR_ARG;
/* This needs tweaking by series/model! */ switch (devc->model->series->protocol) {
if (devc->model->series == RIGOL_DS2000) case PROTOCOL_V1:
*data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources)); *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
else break;
case PROTOCOL_V2:
*data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1); *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
break;
default:
*data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
break;
}
break; break;
default: default:
return SR_ERR_NA; return SR_ERR_NA;
@ -970,10 +990,12 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
devc->analog_frame_size = analog_frame_size(sdi); devc->analog_frame_size = analog_frame_size(sdi);
devc->digital_frame_size = digital_frame_size(sdi); devc->digital_frame_size = digital_frame_size(sdi);
if (devc->model->series <= RIGOL_DS1000) { switch (devc->model->series->protocol) {
case PROTOCOL_V2:
if (rigol_ds_config_set(sdi, ":ACQ:MDEP LONG") != SR_OK) if (rigol_ds_config_set(sdi, ":ACQ:MDEP LONG") != SR_OK)
return SR_ERR; return SR_ERR;
} else { break;
case PROTOCOL_V3:
/* Apparently for the DS2000 the memory /* Apparently for the DS2000 the memory
* depth can only be set in Running state - * depth can only be set in Running state -
* this matches the behaviour of the UI. */ * this matches the behaviour of the UI. */
@ -984,6 +1006,9 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
return SR_ERR; return SR_ERR;
if (rigol_ds_config_set(sdi, ":STOP") != SR_OK) if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
return SR_ERR; return SR_ERR;
break;
default:
break;
} }
if (devc->data_source == DATA_SOURCE_LIVE) if (devc->data_source == DATA_SOURCE_LIVE)

View File

@ -185,7 +185,7 @@ static int rigol_ds_trigger_wait(const struct sr_dev_inst *sdi)
* Timebase * num hor. divs * 85(%) * 1e6(usecs) / 100 * Timebase * num hor. divs * 85(%) * 1e6(usecs) / 100
* -> 85 percent of sweep time * -> 85 percent of sweep time
*/ */
s = (devc->timebase * devc->model->num_horizontal_divs s = (devc->timebase * devc->model->series->num_horizontal_divs
* 85e6) / 100L; * 85e6) / 100L;
sr_spew("Sleeping for %ld usecs instead of trigger-wait", s); sr_spew("Sleeping for %ld usecs instead of trigger-wait", s);
g_usleep(s); g_usleep(s);
@ -215,7 +215,7 @@ static int rigol_ds_check_stop(const struct sr_dev_inst *sdi)
probe = devc->channel_entry->data; probe = devc->channel_entry->data;
if (devc->model->series <= RIGOL_DS1000) if (devc->model->series->protocol <= PROTOCOL_V2)
return SR_OK; return SR_OK;
if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d", if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d",
@ -304,7 +304,7 @@ SR_PRIV int rigol_ds_config_set(const struct sr_dev_inst *sdi, const char *forma
if (ret != SR_OK) if (ret != SR_OK)
return SR_ERR; return SR_ERR;
if (devc->model->series == RIGOL_DS1000) { if (devc->model->series->protocol == PROTOCOL_V2) {
/* The DS1000 series needs this stupid delay, *OPC? doesn't work. */ /* The DS1000 series needs this stupid delay, *OPC? doesn't work. */
sr_spew("delay %dms", 100); sr_spew("delay %dms", 100);
g_usleep(100000); g_usleep(100000);
@ -326,21 +326,16 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi)
sr_dbg("Starting data capture for frameset %lu of %lu", sr_dbg("Starting data capture for frameset %lu of %lu",
devc->num_frames + 1, devc->limit_frames); devc->num_frames + 1, devc->limit_frames);
if (devc->model->series >= RIGOL_DS1000Z) switch (devc->model->series->protocol) {
if (rigol_ds_config_set(sdi, ":WAV:FORM BYTE") != SR_OK) case PROTOCOL_V1:
return SR_ERR;
if (devc->data_source == DATA_SOURCE_LIVE) {
if (devc->model->series <= RIGOL_DS1000) {
if (rigol_ds_config_set(sdi, ":WAV:POIN:MODE NORM") != SR_OK)
return SR_ERR;
} else {
if (rigol_ds_config_set(sdi, ":WAV:MODE NORM") != SR_OK)
return SR_ERR;
}
rigol_ds_set_wait_event(devc, WAIT_TRIGGER); rigol_ds_set_wait_event(devc, WAIT_TRIGGER);
} else { break;
if (devc->model->series <= RIGOL_DS1000) { case PROTOCOL_V2:
if (devc->data_source == DATA_SOURCE_LIVE) {
if (rigol_ds_config_set(sdi, ":WAV:POIN:MODE NORMAL") != SR_OK)
return SR_ERR;
rigol_ds_set_wait_event(devc, WAIT_TRIGGER);
} else {
if (rigol_ds_config_set(sdi, ":STOP") != SR_OK) if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
return SR_ERR; return SR_ERR;
if (rigol_ds_config_set(sdi, ":WAV:POIN:MODE RAW") != SR_OK) if (rigol_ds_config_set(sdi, ":WAV:POIN:MODE RAW") != SR_OK)
@ -351,13 +346,24 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi)
return SR_ERR; return SR_ERR;
if (rigol_ds_config_set(sdi, ":RUN") != SR_OK) if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
return SR_ERR; return SR_ERR;
rigol_ds_set_wait_event(devc, WAIT_STOP);
}
break;
case PROTOCOL_V3:
if (rigol_ds_config_set(sdi, ":WAV:FORM BYTE") != SR_OK)
return SR_ERR;
if (devc->data_source == DATA_SOURCE_LIVE) {
if (rigol_ds_config_set(sdi, ":WAV:MODE NORM") != SR_OK)
return SR_ERR;
rigol_ds_set_wait_event(devc, WAIT_TRIGGER);
} else { } else {
if (rigol_ds_config_set(sdi, ":WAV:MODE RAW") != SR_OK) if (rigol_ds_config_set(sdi, ":WAV:MODE RAW") != SR_OK)
return SR_ERR; return SR_ERR;
if (rigol_ds_config_set(sdi, ":SING") != SR_OK) if (rigol_ds_config_set(sdi, ":SING") != SR_OK)
return SR_ERR; return SR_ERR;
rigol_ds_set_wait_event(devc, WAIT_STOP);
} }
rigol_ds_set_wait_event(devc, WAIT_STOP); break;
} }
return SR_OK; return SR_OK;
@ -376,7 +382,7 @@ SR_PRIV int rigol_ds_channel_start(const struct sr_dev_inst *sdi)
sr_dbg("Starting reading data from channel %d", probe->index + 1); sr_dbg("Starting reading data from channel %d", probe->index + 1);
if (devc->model->series < RIGOL_DS1000Z) { if (devc->model->series->protocol <= PROTOCOL_V2) {
if (probe->type == SR_PROBE_LOGIC) { if (probe->type == SR_PROBE_LOGIC) {
if (sr_scpi_send(sdi->conn, ":WAV:DATA? DIG") != SR_OK) if (sr_scpi_send(sdi->conn, ":WAV:DATA? DIG") != SR_OK)
return SR_ERR; return SR_ERR;
@ -497,14 +503,14 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data)
devc->analog_frame_size : devc->digital_frame_size; devc->analog_frame_size : devc->digital_frame_size;
if (devc->num_block_bytes == 0) { if (devc->num_block_bytes == 0) {
if (devc->model->series >= RIGOL_DS1000Z) if (devc->model->series->protocol >= PROTOCOL_V3)
if (sr_scpi_send(sdi->conn, ":WAV:DATA?") != SR_OK) if (sr_scpi_send(sdi->conn, ":WAV:DATA?") != SR_OK)
return TRUE; return TRUE;
if (sr_scpi_read_begin(scpi) != SR_OK) if (sr_scpi_read_begin(scpi) != SR_OK)
return TRUE; return TRUE;
if (devc->protocol == PROTOCOL_IEEE488_2) { if (devc->format == FORMAT_IEEE488_2) {
sr_dbg("New block header expected"); sr_dbg("New block header expected");
len = rigol_ds_read_header(scpi); len = rigol_ds_read_header(scpi);
if (len == -1) if (len == -1)
@ -542,7 +548,7 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data)
vref = devc->vert_reference[probe->index]; vref = devc->vert_reference[probe->index];
vdiv = devc->vdiv[probe->index] / 25.6; vdiv = devc->vdiv[probe->index] / 25.6;
offset = devc->vert_offset[probe->index]; offset = devc->vert_offset[probe->index];
if (devc->model->series >= RIGOL_DS1000Z) if (devc->model->series->protocol >= PROTOCOL_V3)
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
devc->data[i] = ((int)devc->buffer[i] - vref) * vdiv - offset; devc->data[i] = ((int)devc->buffer[i] - vref) * vdiv - offset;
else else
@ -569,7 +575,7 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data)
if (devc->num_block_read == devc->num_block_bytes) { if (devc->num_block_read == devc->num_block_bytes) {
sr_dbg("Block has been completed"); sr_dbg("Block has been completed");
if (devc->protocol == PROTOCOL_IEEE488_2) { if (devc->format == FORMAT_IEEE488_2) {
/* Discard the terminating linefeed */ /* Discard the terminating linefeed */
sr_scpi_read_data(scpi, (char *)devc->buffer, 1); sr_scpi_read_data(scpi, (char *)devc->buffer, 1);
/* Prepare for possible next block */ /* Prepare for possible next block */
@ -594,7 +600,7 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data)
return TRUE; return TRUE;
/* End of data for this channel. */ /* End of data for this channel. */
if (devc->model->series >= RIGOL_DS1000Z) { if (devc->model->series->protocol >= PROTOCOL_V3) {
/* Signal end of data download to scope */ /* Signal end of data download to scope */
if (devc->data_source != DATA_SOURCE_LIVE) if (devc->data_source != DATA_SOURCE_LIVE)
/* /*
@ -705,7 +711,7 @@ SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi)
sr_dbg("CH%d %g", i + 1, devc->vdiv[i]); sr_dbg("CH%d %g", i + 1, devc->vdiv[i]);
sr_dbg("Current vertical reference:"); sr_dbg("Current vertical reference:");
if (devc->model->series >= RIGOL_DS1000Z) { if (devc->model->series->protocol >= PROTOCOL_V3) {
/* Vertical reference - not certain if this is the place to read it. */ /* Vertical reference - not certain if this is the place to read it. */
for (i = 0; i < devc->model->analog_channels; i++) { for (i = 0; i < devc->model->analog_channels; i++) {
if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d", i + 1) != SR_OK) if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d", i + 1) != SR_OK)

View File

@ -28,39 +28,23 @@
#define LOG_PREFIX "rigol-ds" #define LOG_PREFIX "rigol-ds"
/* Analog waveform block sizes */
#define DS1000_ANALOG_LIVE_WAVEFORM_SIZE 600
#define DS2000_ANALOG_LIVE_WAVEFORM_SIZE 1400
#define VS5000_ANALOG_LIVE_WAVEFORM_SIZE 2048
#define DSO1000_ANALOG_LIVE_WAVEFORM_SIZE 600
#define DS2000_ANALOG_MEM_WAVEFORM_SIZE_1C 14000
#define DS2000_ANALOG_MEM_WAVEFORM_SIZE_2C 7000
/* Digital waveform block size */
#define DS1000_DIGITAL_WAVEFORM_SIZE 1200
#define VS5000_DIGITAL_WAVEFORM_SIZE 4096
/* Size of acquisition buffers */ /* Size of acquisition buffers */
#define ACQ_BUFFER_SIZE 32768 #define ACQ_BUFFER_SIZE 32768
#define MAX_ANALOG_PROBES 4 #define MAX_ANALOG_PROBES 4
#define MAX_DIGITAL_PROBES 16 #define MAX_DIGITAL_PROBES 16
enum rigol_ds_series { enum protocol_version {
RIGOL_VS5000, PROTOCOL_V1, /* VS5000 */
RIGOL_DS1000, PROTOCOL_V2, /* DS1000 */
RIGOL_DS1000Z, PROTOCOL_V3, /* DS2000, DSO1000 */
RIGOL_DS2000,
RIGOL_DS4000,
RIGOL_DS6000,
AGILENT_DSO1000,
}; };
enum rigol_protocol_flavor { enum data_format {
/* Used by DS1000 and VS5000 series */ /* Used by DS1000 versions up to 2.02, and VS5000 series */
PROTOCOL_LEGACY, FORMAT_RAW,
/* Used by DS2000, DS4000, DS6000, ... series */ /* Used by DS1000 versions from 2.04 onwards and all later series */
PROTOCOL_IEEE488_2, FORMAT_IEEE488_2,
}; };
enum data_source { enum data_source {
@ -69,17 +53,29 @@ enum data_source {
DATA_SOURCE_SEGMENTED, DATA_SOURCE_SEGMENTED,
}; };
struct rigol_ds_model { struct rigol_ds_vendor {
char *vendor; const char *name;
char *name; const char *full_name;
enum rigol_ds_series series; };
enum rigol_protocol_flavor protocol;
uint64_t min_timebase[2]; struct rigol_ds_series {
const struct rigol_ds_vendor *vendor;
const char *name;
enum protocol_version protocol;
enum data_format format;
uint64_t max_timebase[2]; uint64_t max_timebase[2];
uint64_t min_vdiv[2]; uint64_t min_vdiv[2];
int num_horizontal_divs;
int live_samples;
int buffer_samples;
};
struct rigol_ds_model {
const struct rigol_ds_series *series;
const char *name;
uint64_t min_timebase[2];
unsigned int analog_channels; unsigned int analog_channels;
bool has_digital; bool has_digital;
int num_horizontal_divs;
}; };
enum wait_events { enum wait_events {
@ -93,7 +89,7 @@ enum wait_events {
struct dev_context { struct dev_context {
/* Device model */ /* Device model */
const struct rigol_ds_model *model; const struct rigol_ds_model *model;
enum rigol_protocol_flavor protocol; enum data_format format;
/* Device properties */ /* Device properties */
const uint64_t (*timebases)[2]; const uint64_t (*timebases)[2];