Skip to content

Commit ac86ac6

Browse files
author
Frederic Borry
committed
Added support for DHO 800/900 models
Based on the work of Diana Ellefson (OrionOth) : sigrokproject#229 and RemiNV : sigrokproject@3430e8e
1 parent f91fb2a commit ac86ac6

File tree

4 files changed

+163
-33
lines changed

4 files changed

+163
-33
lines changed

contrib/60-libsigrok.rules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@ ATTRS{idVendor}=="1ab1", ATTRS{idProduct}=="0e11", ENV{ID_SIGROK}="1"
249249
# Rigol MSO5000 series
250250
ATTRS{idVendor}=="1ab1", ATTRS{idProduct}=="0515", ENV{ID_SIGROK}="1"
251251

252+
# Rigol DHO800 series
253+
ATTRS{idVendor}=="1ab1", ATTRS{idProduct}=="044d", ENV{ID_SIGROK}="1"
254+
255+
# Rigol DHO800 and DHO900 series
256+
ATTRS{idVendor}=="1ab1", ATTRS{idProduct}=="044c", ENV{ID_SIGROK}="1"
257+
252258
# Rohde&Schwarz HMO series mixed-signal oscilloscope (previously branded Hameg) VCP/USBTMC mode
253259
ATTRS{idVendor}=="0aad", ATTRS{idProduct}=="0117", ENV{ID_SIGROK}="1"
254260
ATTRS{idVendor}=="0aad", ATTRS{idProduct}=="0118", ENV{ID_SIGROK}="1"

src/hardware/rigol-ds/api.c

Lines changed: 95 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ static const uint64_t timebases[][2] = {
105105

106106
static const uint64_t vdivs[][2] = {
107107
/* microvolts */
108+
{ 200, 1000000 },
108109
{ 500, 1000000 },
109110
/* millivolts */
110111
{ 1, 1000 },
@@ -185,6 +186,8 @@ enum series {
185186
DS4000,
186187
MSO5000,
187188
MSO7000A,
189+
DHO800,
190+
DHO900,
188191
};
189192

190193
/* short name, full name */
@@ -217,6 +220,10 @@ static const struct rigol_ds_series supported_series[] = {
217220
{1000, 1}, {500, 1000000}, 10, 1000, 0},
218221
[MSO7000A] = {VENDOR(AGILENT), "MSO7000A", PROTOCOL_V4, FORMAT_IEEE488_2,
219222
{50, 1}, {2, 1000}, 10, 1000, 8000000},
223+
[DHO800] = {VENDOR(RIGOL), "DHO800", PROTOCOL_V6, FORMAT_IEEE488_2,
224+
{500, 1}, {500, 1000000}, 10, 1000, 0},
225+
[DHO900] = {VENDOR(RIGOL), "DHO900", PROTOCOL_V6, FORMAT_IEEE488_2,
226+
{500, 1}, {200, 1000000}, 10, 1000, 0},
220227
};
221228

222229
#define SERIES(x) &supported_series[x]
@@ -291,6 +298,14 @@ static const struct rigol_ds_model supported_models[] = {
291298
{SERIES(MSO5000), "MSO5354", {1, 1000000000}, CH_INFO(4, true), std_cmd},
292299
/* TODO: Digital channels are not yet supported on MSO7000A. */
293300
{SERIES(MSO7000A), "MSO7034A", {2, 1000000000}, CH_INFO(4, false), mso7000a_cmd},
301+
{SERIES(DHO800), "DHO802", {5, 1000000000}, CH_INFO(2, false), std_cmd},
302+
{SERIES(DHO800), "DHO804", {5, 1000000000}, CH_INFO(4, false), std_cmd},
303+
{SERIES(DHO800), "DHO812", {5, 1000000000}, CH_INFO(2, false), std_cmd},
304+
{SERIES(DHO800), "DHO814", {5, 1000000000}, CH_INFO(4, false), std_cmd},
305+
{SERIES(DHO900), "DHO914", {2, 1000000000}, CH_INFO(4, true), std_cmd},
306+
{SERIES(DHO900), "DHO914S", {2, 1000000000}, CH_INFO(4, true), std_cmd},
307+
{SERIES(DHO900), "DHO924", {2, 1000000000}, CH_INFO(4, true), std_cmd},
308+
{SERIES(DHO900), "DHO924S", {2, 1000000000}, CH_INFO(4, true), std_cmd},
294309
};
295310

296311
static struct sr_dev_driver rigol_ds_driver_info;
@@ -913,20 +928,45 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
913928
some_digital = TRUE;
914929
/* Turn on LA module if currently off. */
915930
if (!devc->la_enabled) {
916-
if (rigol_ds_config_set(sdi, protocol >= PROTOCOL_V3 ?
917-
":LA:STAT ON" : ":LA:DISP ON") != SR_OK)
931+
switch (protocol) {
932+
case PROTOCOL_V1:
933+
case PROTOCOL_V2:
934+
cmd = ":LA:DISP ON";
935+
break;
936+
case PROTOCOL_V3:
937+
case PROTOCOL_V4:
938+
case PROTOCOL_V5:
939+
cmd = ":LA:STAT ON";
940+
break;
941+
case PROTOCOL_V6:
942+
default:
943+
cmd = ":LA:ENAB ON";
944+
break;
945+
}
946+
if (rigol_ds_config_set(sdi, cmd) != SR_OK)
918947
return SR_ERR;
919948
devc->la_enabled = TRUE;
920949
}
921950
}
922951
if (ch->enabled != devc->digital_channels[ch->index]) {
923952
/* Enabled channel is currently disabled, or vice versa. */
924-
if (protocol >= PROTOCOL_V5)
925-
cmd = ":LA:DISP D%d,%s";
926-
else if (protocol >= PROTOCOL_V3)
927-
cmd = ":LA:DIG%d:DISP %s";
928-
else
929-
cmd = ":DIG%d:TURN %s";
953+
switch (protocol) {
954+
case PROTOCOL_V1:
955+
case PROTOCOL_V2:
956+
cmd = ":DIG%d:TURN %s";
957+
break;
958+
case PROTOCOL_V3:
959+
case PROTOCOL_V4:
960+
cmd = ":LA:DIG%d:DISP %s";
961+
break;
962+
case PROTOCOL_V5:
963+
cmd = ":LA:DISP D%d,%s";
964+
break;
965+
case PROTOCOL_V6:
966+
default:
967+
cmd = ":LA:DIG:ENAB D%d,%s";
968+
break;
969+
}
930970

931971
if (rigol_ds_config_set(sdi, cmd, ch->index,
932972
ch->enabled ? "ON" : "OFF") != SR_OK)
@@ -940,10 +980,29 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
940980
return SR_ERR;
941981

942982
/* Turn off LA module if on and no digital channels selected. */
943-
if (devc->la_enabled && !some_digital)
944-
if (rigol_ds_config_set(sdi,
945-
devc->model->series->protocol >= PROTOCOL_V3 ?
946-
":LA:STAT OFF" : ":LA:DISP OFF") != SR_OK)
983+
if (devc->la_enabled && !some_digital) {
984+
switch (protocol) {
985+
case PROTOCOL_V1:
986+
case PROTOCOL_V2:
987+
cmd = ":LA:DISP OFF";
988+
break;
989+
case PROTOCOL_V3:
990+
case PROTOCOL_V4:
991+
case PROTOCOL_V5:
992+
cmd = ":LA:STAT OFF";
993+
break;
994+
case PROTOCOL_V6:
995+
default:
996+
cmd = ":LA:ENAB OFF";
997+
break;
998+
}
999+
if (rigol_ds_config_set(sdi, cmd) != SR_OK)
1000+
return SR_ERR;
1001+
}
1002+
1003+
/* For DHO scopes, trigger must be in stop mode to start memory or segmented acquisition */
1004+
if((protocol == PROTOCOL_V6)&&((devc->data_source == DATA_SOURCE_SEGMENTED)||(devc->data_source == DATA_SOURCE_MEMORY)))
1005+
if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
9471006
return SR_ERR;
9481007

9491008
/* Set memory mode. */
@@ -969,10 +1028,28 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
9691028
devc->num_frames_segmented = frames;
9701029
break;
9711030
}
1031+
case PROTOCOL_V6:
1032+
/* DHO scopes need to be in UltraAcquire mode for segmented acquisoton */
1033+
/* This command is not working as for firmware version v00.01.02.00.02 of 2023/12/28
1034+
the scope has to be put manually in UltraAcquire mode for segmented acquisition to work */
1035+
//if (rigol_ds_config_set(sdi, ":ACQ:TYPE ULTR") != SR_OK)
1036+
// return SR_ERR; */
1037+
1038+
int frames = 0;
1039+
//if (sr_scpi_get_int(sdi->conn, ":REC:FRAM?", &frames) != SR_OK)
1040+
if (sr_scpi_get_int(sdi->conn, ":ACQ:ULTR:MAXF?", &frames) != SR_OK)
1041+
return SR_ERR;
1042+
if (frames <= 0) {
1043+
sr_err("No segmented data available");
1044+
return SR_ERR;
1045+
}
1046+
devc->num_frames_segmented = frames;
1047+
/* Continue with REC:CURR command */
1048+
// fall through
9721049
case PROTOCOL_V5:
9731050
/* The frame limit has to be read on the fly, just set up
9741051
* reading of the first frame */
975-
if (rigol_ds_config_set(sdi, "REC:CURR 1") != SR_OK)
1052+
if (rigol_ds_config_set(sdi, ":REC:CURR 1") != SR_OK)
9761053
return SR_ERR;
9771054
break;
9781055
default:
@@ -984,7 +1061,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
9841061
devc->analog_frame_size = analog_frame_size(sdi);
9851062
devc->digital_frame_size = digital_frame_size(sdi);
9861063

987-
switch (devc->model->series->protocol) {
1064+
switch (protocol) {
9881065
case PROTOCOL_V2:
9891066
if (rigol_ds_config_set(sdi, ":ACQ:MEMD LONG") != SR_OK)
9901067
return SR_ERR;
@@ -1021,7 +1098,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
10211098
(devc->timebase * devc->model->series->num_horizontal_divs);
10221099
} else {
10231100
float xinc;
1024-
if (devc->model->series->protocol < PROTOCOL_V3) {
1101+
if (protocol < PROTOCOL_V3) {
10251102
sr_err("Cannot get samplerate (below V3).");
10261103
return SR_ERR;
10271104
}
@@ -1037,8 +1114,9 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
10371114
devc->sample_rate = 1. / xinc;
10381115
}
10391116

1040-
if (rigol_ds_capture_start(sdi) != SR_OK)
1041-
return SR_ERR;
1117+
ret = rigol_ds_capture_start(sdi);
1118+
if (ret != SR_OK)
1119+
return ret;
10421120

10431121
/* Start of first frame. */
10441122
std_session_send_df_frame_begin(sdi);

src/hardware/rigol-ds/protocol.c

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,13 @@ SR_PRIV int rigol_ds_config_set(const struct sr_dev_inst *sdi, const char *forma
324324
return SR_ERR;
325325

326326
if (devc->model->series->protocol == PROTOCOL_V2) {
327-
/* The DS1000 series needs this stupid delay, *OPC? doesn't work. */
327+
/* The DS1000 series needs this stupid delay, *OPC? doesn't work.*/
328328
sr_spew("delay %dms", 100);
329329
g_usleep(100 * 1000);
330330
return SR_OK;
331+
} else if (devc->model->series->protocol == PROTOCOL_V6) {
332+
/* Same goes for DHO series but they can handle faster response...*/
333+
return SR_OK;
331334
} else {
332335
return sr_scpi_get_opc(sdi->conn);
333336
}
@@ -385,6 +388,7 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi)
385388
case PROTOCOL_V3:
386389
case PROTOCOL_V4:
387390
case PROTOCOL_V5:
391+
case PROTOCOL_V6:
388392
if (first_frame && rigol_ds_config_set(sdi, ":WAV:FORM BYTE") != SR_OK)
389393
return SR_ERR;
390394
if (devc->data_source == DATA_SOURCE_LIVE) {
@@ -417,13 +421,23 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi)
417421
buffer_samples = devc->model->series->buffer_samples;
418422
if (first_frame && buffer_samples == 0)
419423
{
420-
/* The DS4000 series does not have a fixed memory depth, it
424+
/* The DS4000 and DHO series does not have a fixed memory depth, it
421425
* can be chosen from the menu and also varies with number
422426
* of active channels. Retrieve the actual number with the
423427
* ACQ:MDEP command. */
424428
sr_scpi_get_int(sdi->conn, "ACQ:MDEP?", &buffer_samples);
429+
/* TODO : what about digital channels ? */
425430
devc->analog_frame_size = devc->digital_frame_size =
426431
buffer_samples;
432+
433+
/* For some reason, as for DHO firmware version v00.01.02.00.02 of 2023/12/28,
434+
* segmented acquisition does not work over multiple data blocks : DATA? command on a frame
435+
* portion results in a header, declaring an empty content, of the form '#9000000000'. */
436+
if(devc->data_source == DATA_SOURCE_SEGMENTED && devc->analog_frame_size > ACQ_BLOCK_SIZE) {
437+
sr_err("Data source 'Segmented' not supported for memory depth > %d points.",ACQ_BLOCK_SIZE);
438+
return SR_ERR_NA;
439+
}
440+
427441
}
428442
else if (first_frame)
429443
{
@@ -499,6 +513,7 @@ SR_PRIV int rigol_ds_channel_start(const struct sr_dev_inst *sdi)
499513
break;
500514
case PROTOCOL_V4:
501515
case PROTOCOL_V5:
516+
case PROTOCOL_V6:
502517
if (ch->type == SR_CHANNEL_ANALOG) {
503518
if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d",
504519
ch->index + 1) != SR_OK)
@@ -514,7 +529,7 @@ SR_PRIV int rigol_ds_channel_start(const struct sr_dev_inst *sdi)
514529
":WAV:MODE NORM" :":WAV:MODE RAW") != SR_OK)
515530
return SR_ERR;
516531

517-
if (devc->data_source != DATA_SOURCE_LIVE) {
532+
if ((devc->data_source != DATA_SOURCE_LIVE) && (devc->model->series->protocol != PROTOCOL_V6)) {
518533
if (rigol_ds_config_set(sdi, ":WAV:RES") != SR_OK)
519534
return SR_ERR;
520535
}
@@ -669,17 +684,17 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data)
669684

670685
if (devc->num_block_bytes == 0) {
671686
if (devc->model->series->protocol >= PROTOCOL_V4) {
672-
if (first_frame && rigol_ds_config_set(sdi, ":WAV:START %d",
687+
if ((first_frame || (devc->model->series->protocol == PROTOCOL_V6)) && rigol_ds_config_set(sdi, ":WAV:START %d",
673688
devc->num_channel_bytes + 1) != SR_OK)
674689
return TRUE;
675-
if (first_frame && rigol_ds_config_set(sdi, ":WAV:STOP %d",
690+
if ((first_frame || (devc->model->series->protocol == PROTOCOL_V6)) && rigol_ds_config_set(sdi, ":WAV:STOP %d",
676691
MIN(devc->num_channel_bytes + ACQ_BLOCK_SIZE,
677692
devc->analog_frame_size)) != SR_OK)
678693
return TRUE;
679694
}
680695

681696
if (devc->model->series->protocol >= PROTOCOL_V3) {
682-
if (rigol_ds_config_set(sdi, ":WAV:BEG") != SR_OK)
697+
if ((devc->model->series->protocol != PROTOCOL_V6) && rigol_ds_config_set(sdi, ":WAV:BEG") != SR_OK)
683698
return TRUE;
684699
if (sr_scpi_send(sdi->conn, ":WAV:DATA?") != SR_OK)
685700
return TRUE;
@@ -846,6 +861,13 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data)
846861
/* Get the next frame, starting with the first channel. */
847862
devc->channel_entry = devc->enabled_channels;
848863

864+
if (devc->data_source == DATA_SOURCE_SEGMENTED &&
865+
devc->model->series->protocol == PROTOCOL_V6) {
866+
/* Move to next frame in segmented mode*/
867+
if (rigol_ds_config_set(sdi, ":REC:CURR %d", devc->num_frames + 1) != SR_OK)
868+
return SR_ERR;
869+
}
870+
849871
rigol_ds_capture_start(sdi);
850872

851873
/* Start of next frame. */
@@ -882,20 +904,43 @@ SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi)
882904

883905
/* Digital channel state. */
884906
if (devc->model->has_digital) {
885-
if (sr_scpi_get_bool(sdi->conn,
886-
devc->model->series->protocol >= PROTOCOL_V3 ?
887-
":LA:STAT?" : ":LA:DISP?",
888-
&devc->la_enabled) != SR_OK)
907+
switch (devc->model->series->protocol) {
908+
case PROTOCOL_V1:
909+
case PROTOCOL_V2:
910+
cmd = ":LA:DISP?";
911+
break;
912+
case PROTOCOL_V3:
913+
case PROTOCOL_V4:
914+
case PROTOCOL_V5:
915+
cmd = ":LA:STAT?";
916+
break;
917+
case PROTOCOL_V6:
918+
default:
919+
cmd = ":LA:ENAB?";
920+
break;
921+
}
922+
if (sr_scpi_get_bool(sdi->conn, cmd, &devc->la_enabled) != SR_OK)
889923
return SR_ERR;
890924
sr_dbg("Logic analyzer %s, current digital channel state:",
891925
devc->la_enabled ? "enabled" : "disabled");
892926
for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) {
893-
if (devc->model->series->protocol >= PROTOCOL_V5)
894-
cmd = g_strdup_printf(":LA:DISP? D%d", i);
895-
else if (devc->model->series->protocol >= PROTOCOL_V3)
896-
cmd = g_strdup_printf(":LA:DIG%d:DISP?", i);
897-
else
898-
cmd = g_strdup_printf(":DIG%d:TURN?", i);
927+
switch (devc->model->series->protocol) {
928+
case PROTOCOL_V1:
929+
case PROTOCOL_V2:
930+
cmd = g_strdup_printf(":DIG%d:TURN?", i);
931+
break;
932+
case PROTOCOL_V3:
933+
case PROTOCOL_V4:
934+
cmd = g_strdup_printf(":LA:DIG%d:DISP?", i);
935+
break;
936+
case PROTOCOL_V5:
937+
cmd = g_strdup_printf(":LA:DISP? D%d", i);
938+
break;
939+
case PROTOCOL_V6:
940+
default:
941+
cmd = g_strdup_printf(":LA:DIG:ENAB? D%d", i);
942+
break;
943+
}
899944
res = sr_scpi_get_bool(sdi->conn, cmd, &devc->digital_channels[i]);
900945
g_free(cmd);
901946
if (res != SR_OK)

src/hardware/rigol-ds/protocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum protocol_version {
4343
PROTOCOL_V3, /* DS2000, DSO1000 */
4444
PROTOCOL_V4, /* DS1000Z */
4545
PROTOCOL_V5, /* MSO5000 */
46+
PROTOCOL_V6, /* DHO800, DHO900 */
4647
};
4748

4849
enum data_format {

0 commit comments

Comments
 (0)