diff --git a/src/hardware/rigol-ds/api.c b/src/hardware/rigol-ds/api.c index a142a2d8..60d63d59 100644 --- a/src/hardware/rigol-ds/api.c +++ b/src/hardware/rigol-ds/api.c @@ -175,6 +175,7 @@ enum series { DS2000, DS2000A, DSO1000, + DS1000Z, }; /* short name, full name */ @@ -197,6 +198,8 @@ static const struct rigol_ds_series supported_series[] = { {1000, 1}, {500, 1000000}, 14, 1400, 14000}, [DSO1000] = {VENDOR(AGILENT), "DSO1000", PROTOCOL_V3, FORMAT_IEEE488_2, {50, 1}, {2, 1000}, 12, 600, 20480}, + [DS1000Z] = {VENDOR(RIGOL), "DS1000Z", PROTOCOL_V4, FORMAT_IEEE488_2, + {50, 1}, {1, 1000}, 12, 1200, 12000000}, }; #define SERIES(x) &supported_series[x] @@ -232,6 +235,15 @@ static const struct rigol_ds_model supported_models[] = { {SERIES(DSO1000), "DSO1014A", {2, 1000000000}, 4, false}, {SERIES(DSO1000), "DSO1022A", {2, 1000000000}, 2, false}, {SERIES(DSO1000), "DSO1024A", {2, 1000000000}, 4, false}, + {SERIES(DS1000Z), "DS1054Z", {5, 1000000000}, 4, false}, + {SERIES(DS1000Z), "DS1074Z", {5, 1000000000}, 4, false}, + {SERIES(DS1000Z), "DS1104Z", {5, 1000000000}, 4, false}, + {SERIES(DS1000Z), "DS1074Z-S", {5, 1000000000}, 4, false}, + {SERIES(DS1000Z), "DS1104Z-S", {5, 1000000000}, 4, false}, + {SERIES(DS1000Z), "MSO1074Z", {5, 1000000000}, 4, true}, + {SERIES(DS1000Z), "MSO1104Z", {5, 1000000000}, 4, true}, + {SERIES(DS1000Z), "MSO1074Z-S", {5, 1000000000}, 4, true}, + {SERIES(DS1000Z), "MSO1104Z-S", {5, 1000000000}, 4, true}, }; SR_PRIV struct sr_dev_driver rigol_ds_driver_info; @@ -923,6 +935,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) struct dev_context *devc; struct sr_channel *ch; struct sr_datafeed_packet packet; + gboolean some_digital; GSList *l; if (sdi->status != SR_ST_ACTIVE) @@ -933,13 +946,14 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) devc->num_frames = 0; + some_digital = FALSE; for (l = sdi->channels; l; l = l->next) { ch = l->data; sr_dbg("handling channel %s", ch->name); if (ch->type == SR_CHANNEL_ANALOG) { if (ch->enabled) - devc->enabled_analog_channels = g_slist_append( - devc->enabled_analog_channels, ch); + devc->enabled_channels = g_slist_append( + devc->enabled_channels, ch); if (ch->enabled != devc->analog_channels[ch->index]) { /* Enabled channel is currently disabled, or vice versa. */ if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", ch->index + 1, @@ -948,19 +962,29 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) devc->analog_channels[ch->index] = ch->enabled; } } else if (ch->type == SR_CHANNEL_LOGIC) { + /* Only one list entry for DS1000D series. All channels are retrieved + * together when this entry is processed. */ + if (ch->enabled && ( + devc->model->series->protocol > PROTOCOL_V2 || + !some_digital)) + devc->enabled_channels = g_slist_append( + devc->enabled_channels, ch); if (ch->enabled) { - devc->enabled_digital_channels = g_slist_append( - devc->enabled_digital_channels, ch); + some_digital = TRUE; /* Turn on LA module if currently off. */ if (!devc->la_enabled) { - if (rigol_ds_config_set(sdi, ":LA:DISP ON") != SR_OK) + if (rigol_ds_config_set(sdi, + devc->model->series->protocol >= PROTOCOL_V4 ? + ":LA:STAT ON" : ":LA:DISP ON") != SR_OK) return SR_ERR; devc->la_enabled = TRUE; } } if (ch->enabled != devc->digital_channels[ch->index]) { /* Enabled channel is currently disabled, or vice versa. */ - if (rigol_ds_config_set(sdi, ":DIG%d:TURN %s", ch->index, + if (rigol_ds_config_set(sdi, + devc->model->series->protocol >= PROTOCOL_V4 ? + ":LA:DIG%d:DISP %s" : ":DIG%d:TURN %s", ch->index, ch->enabled ? "ON" : "OFF") != SR_OK) return SR_ERR; devc->digital_channels[ch->index] = ch->enabled; @@ -968,12 +992,14 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) } } - if (!devc->enabled_analog_channels && !devc->enabled_digital_channels) + if (!devc->enabled_channels) return SR_ERR; /* Turn off LA module if on and no digital channels selected. */ - if (devc->la_enabled && !devc->enabled_digital_channels) - if (rigol_ds_config_set(sdi, ":LA:DISP OFF") != SR_OK) + if (devc->la_enabled && !some_digital) + if (rigol_ds_config_set(sdi, + devc->model->series->protocol >= PROTOCOL_V4 ? + ":LA:STAT OFF" : ":LA:DISP OFF") != SR_OK) return SR_ERR; /* Set memory mode. */ @@ -1016,10 +1042,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) /* Send header packet to the session bus. */ std_session_send_df_header(cb_data, LOG_PREFIX); - if (devc->enabled_analog_channels) - devc->channel_entry = devc->enabled_analog_channels; - else - devc->channel_entry = devc->enabled_digital_channels; + devc->channel_entry = devc->enabled_channels; if (rigol_ds_capture_start(sdi) != SR_OK) return SR_ERR; @@ -1050,10 +1073,8 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) packet.type = SR_DF_END; sr_session_send(sdi, &packet); - g_slist_free(devc->enabled_analog_channels); - g_slist_free(devc->enabled_digital_channels); - devc->enabled_analog_channels = NULL; - devc->enabled_digital_channels = NULL; + g_slist_free(devc->enabled_channels); + devc->enabled_channels = NULL; scpi = sdi->conn; sr_scpi_source_remove(sdi->session, scpi); diff --git a/src/hardware/rigol-ds/protocol.c b/src/hardware/rigol-ds/protocol.c index 3197d191..8a144f1b 100644 --- a/src/hardware/rigol-ds/protocol.c +++ b/src/hardware/rigol-ds/protocol.c @@ -215,7 +215,7 @@ static int rigol_ds_check_stop(const struct sr_dev_inst *sdi) ch = devc->channel_entry->data; - if (devc->model->series->protocol <= PROTOCOL_V2) + if (devc->model->series->protocol != PROTOCOL_V3) return SR_OK; if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d", @@ -261,7 +261,7 @@ static int rigol_ds_block_wait(const struct sr_dev_inst *sdi) if (!(devc = sdi->priv)) return SR_ERR; - if (devc->model->series->protocol >= PROTOCOL_V3) { + if (devc->model->series->protocol == PROTOCOL_V3) { start = time(NULL); @@ -322,6 +322,7 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi) { struct dev_context *devc; gchar *trig_mode; + unsigned int num_channels, i, j; if (!(devc = sdi->priv)) return SR_ERR; @@ -353,15 +354,44 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi) } break; case PROTOCOL_V3: + case PROTOCOL_V4: 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; + devc->analog_frame_size = devc->model->series->live_samples; + devc->digital_frame_size = devc->model->series->live_samples; rigol_ds_set_wait_event(devc, WAIT_TRIGGER); } else { - if (rigol_ds_config_set(sdi, ":WAV:MODE RAW") != SR_OK) - return SR_ERR; + if (devc->model->series->protocol == PROTOCOL_V3) { + if (rigol_ds_config_set(sdi, ":WAV:MODE RAW") != SR_OK) + return SR_ERR; + } else if (devc->model->series->protocol == PROTOCOL_V4) { + num_channels = 0; + + /* Channels 3 and 4 are multiplexed with D0-7 and D8-15 */ + for (i = 0; i < devc->model->analog_channels; i++) { + if (devc->analog_channels[i]) { + num_channels++; + } else if (i >= 2 && devc->model->has_digital) { + for (j = 0; j < 8; j++) { + if (devc->digital_channels[8 * (i - 2) + j]) { + num_channels++; + break; + } + } + } + } + + devc->analog_frame_size = devc->digital_frame_size = + num_channels == 1 ? + devc->model->series->buffer_samples : + num_channels == 2 ? + devc->model->series->buffer_samples / 2 : + devc->model->series->buffer_samples / 4; + } + if (rigol_ds_config_set(sdi, ":SING") != SR_OK) return SR_ERR; rigol_ds_set_wait_event(devc, WAIT_STOP); @@ -385,7 +415,10 @@ SR_PRIV int rigol_ds_channel_start(const struct sr_dev_inst *sdi) sr_dbg("Starting reading data from channel %d", ch->index + 1); - if (devc->model->series->protocol <= PROTOCOL_V2) { + switch (devc->model->series->protocol) + { + case PROTOCOL_V1: + case PROTOCOL_V2: if (ch->type == SR_CHANNEL_LOGIC) { if (sr_scpi_send(sdi->conn, ":WAV:DATA? DIG") != SR_OK) return SR_ERR; @@ -395,7 +428,8 @@ SR_PRIV int rigol_ds_channel_start(const struct sr_dev_inst *sdi) return SR_ERR; } rigol_ds_set_wait_event(devc, WAIT_NONE); - } else { + break; + case PROTOCOL_V3: if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d", ch->index + 1) != SR_OK) return SR_ERR; @@ -405,6 +439,31 @@ SR_PRIV int rigol_ds_channel_start(const struct sr_dev_inst *sdi) if (rigol_ds_config_set(sdi, ":WAV:BEG") != SR_OK) return SR_ERR; } + break; + case PROTOCOL_V4: + if (ch->type == SR_CHANNEL_ANALOG) { + if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d", + ch->index + 1) != SR_OK) + return SR_ERR; + } else { + if (rigol_ds_config_set(sdi, ":WAV:SOUR D%d", + ch->index) != SR_OK) + return SR_ERR; + } + + if (rigol_ds_config_set(sdi, + devc->data_source == DATA_SOURCE_LIVE ? + ":WAV:MODE NORM" :":WAV:MODE RAW") != SR_OK) + return SR_ERR; + break; + } + + if (devc->model->series->protocol >= PROTOCOL_V3 && + ch->type == SR_CHANNEL_ANALOG) { + /* Vertical reference. */ + if (sr_scpi_get_int(sdi->conn, ":WAV:YREF?", + &devc->vert_reference[ch->index]) != SR_OK) + return SR_ERR; } rigol_ds_set_wait_event(devc, WAIT_BLOCK); @@ -529,6 +588,16 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) devc->analog_frame_size : devc->digital_frame_size; if (devc->num_block_bytes == 0) { + if (devc->model->series->protocol >= PROTOCOL_V4) { + if (sr_scpi_send(sdi->conn, ":WAV:START %d", + devc->num_channel_bytes + 1) != SR_OK) + return TRUE; + if (sr_scpi_send(sdi->conn, ":WAV:STOP %d", + MIN(devc->num_channel_bytes + ACQ_BLOCK_SIZE, + devc->analog_frame_size)) != SR_OK) + return TRUE; + } + if (devc->model->series->protocol >= PROTOCOL_V3) if (sr_scpi_send(sdi->conn, ":WAV:DATA?") != SR_OK) return TRUE; @@ -609,7 +678,10 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) g_slist_free(analog.channels); } else { logic.length = len; - logic.unitsize = 2; + // TODO: For the MSO1000Z series, we need a way to express that + // this data is in fact just for a single channel, with the valid + // data for that channel in the LSB of each byte. + logic.unitsize = devc->model->series->protocol == PROTOCOL_V4 ? 1 : 2; logic.data = devc->buffer; packet.type = SR_DF_LOGIC; packet.payload = &logic; @@ -648,7 +720,7 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) return TRUE; /* End of data for this channel. */ - if (devc->model->series->protocol >= PROTOCOL_V3) { + if (devc->model->series->protocol == PROTOCOL_V3) { /* Signal end of data download to scope */ if (devc->data_source != DATA_SOURCE_LIVE) /* @@ -659,40 +731,27 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) rigol_ds_config_set(sdi, ":WAV:END"); } - if (ch->type == SR_CHANNEL_ANALOG - && devc->channel_entry->next != NULL) { - /* We got the frame for this analog channel, but - * there's another analog channel. */ + if (devc->channel_entry->next) { + /* We got the frame for this channel, now get the next channel. */ devc->channel_entry = devc->channel_entry->next; rigol_ds_channel_start(sdi); } else { - /* Done with all analog channels in this frame. */ - if (devc->enabled_digital_channels - && devc->channel_entry != devc->enabled_digital_channels) { - /* Now we need to get the digital data. */ - devc->channel_entry = devc->enabled_digital_channels; - rigol_ds_channel_start(sdi); + /* Done with this frame. */ + packet.type = SR_DF_FRAME_END; + sr_session_send(cb_data, &packet); + + if (++devc->num_frames == devc->limit_frames) { + /* Last frame, stop capture. */ + sdi->driver->dev_acquisition_stop(sdi, cb_data); } else { - /* Done with this frame. */ - packet.type = SR_DF_FRAME_END; + /* Get the next frame, starting with the first channel. */ + devc->channel_entry = devc->enabled_channels; + + rigol_ds_capture_start(sdi); + + /* Start of next frame. */ + packet.type = SR_DF_FRAME_BEGIN; sr_session_send(cb_data, &packet); - - if (++devc->num_frames == devc->limit_frames) { - /* Last frame, stop capture. */ - sdi->driver->dev_acquisition_stop(sdi, cb_data); - } else { - /* Get the next frame, starting with the first analog channel. */ - if (devc->enabled_analog_channels) - devc->channel_entry = devc->enabled_analog_channels; - else - devc->channel_entry = devc->enabled_digital_channels; - - rigol_ds_capture_start(sdi); - - /* Start of next frame. */ - packet.type = SR_DF_FRAME_BEGIN; - sr_session_send(cb_data, &packet); - } } } } @@ -723,13 +782,17 @@ SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi) /* Digital channel state. */ if (devc->model->has_digital) { - if (sr_scpi_get_bool(sdi->conn, ":LA:DISP?", + if (sr_scpi_get_bool(sdi->conn, + devc->model->series->protocol >= PROTOCOL_V4 ? + ":LA:STAT?" : ":LA:DISP?", &devc->la_enabled) != SR_OK) return SR_ERR; sr_dbg("Logic analyzer %s, current digital channel state:", devc->la_enabled ? "enabled" : "disabled"); for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) { - cmd = g_strdup_printf(":DIG%d:TURN?", i); + cmd = g_strdup_printf( + devc->model->series->protocol >= PROTOCOL_V4 ? + ":LA:DIG%d:DISP?" : ":DIG%d:TURN?", i); res = sr_scpi_get_bool(sdi->conn, cmd, &devc->digital_channels[i]); g_free(cmd); if (res != SR_OK) @@ -755,18 +818,6 @@ SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi) for (i = 0; i < devc->model->analog_channels; i++) sr_dbg("CH%d %g", i + 1, devc->vdiv[i]); - sr_dbg("Current vertical reference:"); - if (devc->model->series->protocol >= PROTOCOL_V3) { - /* Vertical reference - not certain if this is the place to read it. */ - for (i = 0; i < devc->model->analog_channels; i++) { - if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d", i + 1) != SR_OK) - return SR_ERR; - if (sr_scpi_get_int(sdi->conn, ":WAV:YREF?", &devc->vert_reference[i]) != SR_OK) - return SR_ERR; - sr_dbg("CH%d %d", i + 1, devc->vert_reference[i]); - } - } - /* Vertical offset. */ for (i = 0; i < devc->model->analog_channels; i++) { cmd = g_strdup_printf(":CHAN%d:OFFS?", i + 1); diff --git a/src/hardware/rigol-ds/protocol.h b/src/hardware/rigol-ds/protocol.h index 7bdf683d..631c81db 100644 --- a/src/hardware/rigol-ds/protocol.h +++ b/src/hardware/rigol-ds/protocol.h @@ -31,6 +31,9 @@ /* Size of acquisition buffers */ #define ACQ_BUFFER_SIZE 32768 +/* Maximum number of samples to retrieve at once. */ +#define ACQ_BLOCK_SIZE 30000 + #define MAX_ANALOG_CHANNELS 4 #define MAX_DIGITAL_CHANNELS 16 @@ -38,6 +41,7 @@ enum protocol_version { PROTOCOL_V1, /* VS5000 */ PROTOCOL_V2, /* DS1000 */ PROTOCOL_V3, /* DS2000, DSO1000 */ + PROTOCOL_V4, /* DS1000Z */ }; enum data_format { @@ -102,8 +106,7 @@ struct dev_context { struct sr_channel_group *digital_group; /* Acquisition settings */ - GSList *enabled_analog_channels; - GSList *enabled_digital_channels; + GSList *enabled_channels; uint64_t limit_frames; void *cb_data; enum data_source data_source;