X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Frigol-ds%2Fprotocol.c;h=688dcc3998750909bbbe228c79590407faef8251;hb=4c5f70063ad6ae311809ee7818ddc9070fbe05cf;hp=e68fb08e68bcc184f16db9ae622fb3625cac0832;hpb=01dd7a4cc769d3e683cb29c5cf791e9c61034f31;p=libsigrok.git diff --git a/src/hardware/rigol-ds/protocol.c b/src/hardware/rigol-ds/protocol.c index e68fb08e..688dcc39 100644 --- a/src/hardware/rigol-ds/protocol.c +++ b/src/hardware/rigol-ds/protocol.c @@ -177,7 +177,7 @@ static int rigol_ds_trigger_wait(const struct sr_dev_inst *sdi) if (!(devc = sdi->priv)) return SR_ERR; - /* + /* * If timebase < 50 msecs/DIV just sleep about one sweep time except * for really fast sweeps. */ @@ -221,7 +221,7 @@ static int rigol_ds_check_stop(const struct sr_dev_inst *sdi) return SR_OK; if (ch->type == SR_CHANNEL_LOGIC) { - if (rigol_ds_config_set(sdi->conn, ":WAV:SOUR LA") != SR_OK) + if (rigol_ds_config_set(sdi, ":WAV:SOUR LA") != SR_OK) return SR_ERR; } else { if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d", @@ -333,12 +333,17 @@ 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; + int buffer_samples; if (!(devc = sdi->priv)) return SR_ERR; - sr_dbg("Starting data capture for frameset %" PRIu64 " of %" PRIu64, - devc->num_frames + 1, devc->limit_frames); + if (devc->limit_frames == 0) + sr_dbg("Starting data capture for frameset %" PRIu64, + devc->num_frames + 1); + else + sr_dbg("Starting data capture for frameset %" PRIu64 " of %" + PRIu64, devc->num_frames + 1, devc->limit_frames); switch (devc->model->series->protocol) { case PROTOCOL_V1: @@ -365,6 +370,7 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi) break; case PROTOCOL_V3: case PROTOCOL_V4: + case PROTOCOL_V5: if (rigol_ds_config_set(sdi, ":WAV:FORM BYTE") != SR_OK) return SR_ERR; if (devc->data_source == DATA_SOURCE_LIVE) { @@ -377,7 +383,7 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi) 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) { + } else if (devc->model->series->protocol >= PROTOCOL_V4) { num_channels = 0; /* Channels 3 and 4 are multiplexed with D0-7 and D8-15 */ @@ -394,12 +400,29 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi) } } - 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; + buffer_samples = devc->model->series->buffer_samples; + if (buffer_samples == 0) + { + /* The DS4000 series does not have a fixed memory depth, it + * can be chosen from the menu and also varies with number + * of active channels. Retrieve the actual number with the + * ACQ:MDEP command. */ + sr_scpi_get_int(sdi->conn, "ACQ:MDEP?", &buffer_samples); + devc->analog_frame_size = devc->digital_frame_size = + buffer_samples; + } + else + { + /* The DS1000Z series has a fixed memory depth which we + * need to divide correctly according to the number of + * active channels. */ + devc->analog_frame_size = devc->digital_frame_size = + num_channels == 1 ? + buffer_samples : + num_channels == 2 ? + buffer_samples / 2 : + buffer_samples / 4; + } } if (rigol_ds_config_set(sdi, ":SING") != SR_OK) @@ -440,7 +463,7 @@ SR_PRIV int rigol_ds_channel_start(const struct sr_dev_inst *sdi) break; case PROTOCOL_V3: if (ch->type == SR_CHANNEL_LOGIC) { - if (rigol_ds_config_set(sdi->conn, ":WAV:SOUR LA") != SR_OK) + if (rigol_ds_config_set(sdi, ":WAV:SOUR LA") != SR_OK) return SR_ERR; } else { if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d", @@ -455,6 +478,7 @@ SR_PRIV int rigol_ds_channel_start(const struct sr_dev_inst *sdi) } break; case PROTOCOL_V4: + case PROTOCOL_V5: if (ch->type == SR_CHANNEL_ANALOG) { if (rigol_ds_config_set(sdi, ":WAV:SOUR CHAN%d", ch->index + 1) != SR_OK) @@ -474,10 +498,20 @@ SR_PRIV int rigol_ds_channel_start(const struct sr_dev_inst *sdi) if (devc->model->series->protocol >= PROTOCOL_V3 && ch->type == SR_CHANNEL_ANALOG) { + /* Vertical increment. */ + if (sr_scpi_get_float(sdi->conn, ":WAV:YINC?", + &devc->vert_inc[ch->index]) != SR_OK) + return SR_ERR; + /* Vertical origin. */ + if (sr_scpi_get_float(sdi->conn, ":WAV:YOR?", + &devc->vert_origin[ch->index]) != SR_OK) + return SR_ERR; /* Vertical reference. */ if (sr_scpi_get_int(sdi->conn, ":WAV:YREF?", &devc->vert_reference[ch->index]) != SR_OK) return SR_ERR; + } else if (ch->type == SR_CHANNEL_ANALOG) { + devc->vert_inc[ch->index] = devc->vdiv[ch->index] / 25.6; } rigol_ds_set_wait_event(devc, WAIT_BLOCK); @@ -557,7 +591,7 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) struct sr_analog_meaning meaning; struct sr_analog_spec spec; struct sr_datafeed_logic logic; - double vdiv, offset; + double vdiv, offset, origin; int len, i, vref; struct sr_channel *ch; gsize expected_data_bytes; @@ -631,10 +665,9 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) /* Still reading the header. */ return TRUE; if (len == -1) { - sr_err("Read error, aborting capture."); - packet.type = SR_DF_FRAME_END; - sr_session_send(sdi, &packet); - sdi->driver->dev_acquisition_stop(sdi); + sr_err("Error while reading block header, aborting capture."); + std_session_send_df_frame_end(sdi); + sr_dev_acquisition_stop(sdi); return TRUE; } /* At slow timebases in live capture the DS2072 @@ -664,10 +697,9 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) len = sr_scpi_read_data(scpi, (char *)devc->buffer, len); if (len == -1) { - sr_err("Read error, aborting capture."); - packet.type = SR_DF_FRAME_END; - sr_session_send(sdi, &packet); - sdi->driver->dev_acquisition_stop(sdi); + sr_err("Error while reading block data, aborting capture."); + std_session_send_df_frame_end(sdi); + sr_dev_acquisition_stop(sdi); return TRUE; } @@ -677,11 +709,12 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) if (ch->type == SR_CHANNEL_ANALOG) { vref = devc->vert_reference[ch->index]; - vdiv = devc->vdiv[ch->index] / 25.6; + vdiv = devc->vert_inc[ch->index]; + origin = devc->vert_origin[ch->index]; offset = devc->vert_offset[ch->index]; if (devc->model->series->protocol >= PROTOCOL_V3) for (i = 0; i < len; i++) - devc->data[i] = ((int)devc->buffer[i] - vref) * vdiv - offset; + devc->data[i] = ((int)devc->buffer[i] - vref - origin) * vdiv; else for (i = 0; i < len; i++) devc->data[i] = (128 - devc->buffer[i]) * vdiv - offset; @@ -703,7 +736,7 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) // 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.unitsize = devc->model->series->protocol >= PROTOCOL_V4 ? 1 : 2; logic.data = devc->buffer; packet.type = SR_DF_LOGIC; packet.payload = &logic; @@ -723,11 +756,11 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) if (devc->data_source != DATA_SOURCE_LIVE) rigol_ds_set_wait_event(devc, WAIT_BLOCK); } - if (!sr_scpi_read_complete(scpi)) { + /* End acquisition when data for all channels is acquired. */ + if (!sr_scpi_read_complete(scpi) && !devc->channel_entry->next) { sr_err("Read should have been completed"); - packet.type = SR_DF_FRAME_END; - sr_session_send(sdi, &packet); - sdi->driver->dev_acquisition_stop(sdi); + std_session_send_df_frame_end(sdi); + sr_dev_acquisition_stop(sdi); return TRUE; } devc->num_block_read = 0; @@ -760,12 +793,11 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) rigol_ds_channel_start(sdi); } else { /* Done with this frame. */ - packet.type = SR_DF_FRAME_END; - sr_session_send(sdi, &packet); + std_session_send_df_frame_end(sdi); if (++devc->num_frames == devc->limit_frames) { /* Last frame, stop capture. */ - sdi->driver->dev_acquisition_stop(sdi); + sr_dev_acquisition_stop(sdi); } else { /* Get the next frame, starting with the first channel. */ devc->channel_entry = devc->enabled_channels; @@ -773,8 +805,7 @@ SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data) rigol_ds_capture_start(sdi); /* Start of next frame. */ - packet.type = SR_DF_FRAME_BEGIN; - sr_session_send(sdi, &packet); + std_session_send_df_frame_begin(sdi); } } @@ -815,9 +846,12 @@ SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi) 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( - devc->model->series->protocol >= PROTOCOL_V3 ? - ":LA:DIG%d:DISP?" : ":DIG%d:TURN?", i); + if (devc->model->series->protocol >= PROTOCOL_V5) + cmd = g_strdup_printf(":LA:DISP? D%d", i); + else if (devc->model->series->protocol >= PROTOCOL_V3) + cmd = g_strdup_printf(":LA:DIG%d:DISP?", i); + else + cmd = g_strdup_printf(":DIG%d:TURN?", i); res = sr_scpi_get_bool(sdi->conn, cmd, &devc->digital_channels[i]); g_free(cmd); if (res != SR_OK) @@ -867,7 +901,8 @@ SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi) sr_dbg("Current trigger source %s", devc->trigger_source); /* Horizontal trigger position. */ - if (sr_scpi_get_float(sdi->conn, ":TIM:OFFS?", &devc->horiz_triggerpos) != SR_OK) + if (sr_scpi_get_float(sdi->conn, devc->model->cmds[CMD_GET_HORIZ_TRIGGERPOS].str, + &devc->horiz_triggerpos) != SR_OK) return SR_ERR; sr_dbg("Current horizontal trigger position %g", devc->horiz_triggerpos);