]> sigrok.org Git - libsigrok.git/blame - src/hardware/siglent-sds/protocol.c
siglent-sds: Various cosmetics and coding-style fixes.
[libsigrok.git] / src / hardware / siglent-sds / protocol.c
CommitLineData
89f5fab9 1/*
2 * This file is part of the libsigrok project.
3 *
b3360671 4 * Copyright (C) 2016 mhooijboer <marchelh@gmail.com>
b3360671 5 * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
6 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
7 * Copyright (C) 2013 Mathias Grimmberger <mgri@zaphod.sax.de>
89f5fab9 8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
b3360671 23#define _GNU_SOURCE
24
89f5fab9 25#include <config.h>
b3360671 26#include <errno.h>
27#include <glib.h>
28#include <glib-2.0/glib/gmacros.h>
29#include <glib-2.0/glib/gmain.h>
30#include <math.h>
31#include <stdlib.h>
32#include <stdarg.h>
33#include <string.h>
34#include <time.h>
35#include <unistd.h>
b3360671 36#include <libsigrok/libsigrok.h>
37#include "libsigrok-internal.h"
38#include "scpi.h"
89f5fab9 39#include "protocol.h"
40
3e7fb88f 41/* Set the next event to wait for in siglent_sds_receive(). */
b3360671 42static void siglent_sds_set_wait_event(struct dev_context *devc, enum wait_events event)
43{
b3360671 44 if (event == WAIT_STOP) {
45 devc->wait_status = 2;
46 } else {
47 devc->wait_status = 1;
48 devc->wait_event = event;
49 }
50}
51
52/*
53 * Waiting for a event will return a timeout after 2 to 3 seconds in order
54 * to not block the application.
55 */
56static int siglent_sds_event_wait(const struct sr_dev_inst *sdi)
57{
58 char *buf;
59 long s;
60 int out;
61 struct dev_context *devc;
62 time_t start;
63
64 if (!(devc = sdi->priv))
65 return SR_ERR;
66
67 start = time(NULL);
68
3e7fb88f 69 s = 10000; /* Sleep time for status refresh. */
b3360671 70 if (devc->wait_status == 1) {
71 do {
72 if (time(NULL) - start >= 3) {
3e7fb88f 73 sr_dbg("Timeout waiting for trigger.");
b3360671 74 return SR_ERR_TIMEOUT;
75 }
76
77 if (sr_scpi_get_string(sdi->conn, ":INR?", &buf) != SR_OK)
78 return SR_ERR;
79 sr_atoi(buf, &out);
80 g_usleep(s);
81 } while (out == 0);
b3360671 82
3e7fb88f
UH
83 sr_dbg("Device triggered.");
84
85 if ((devc->timebase < 0.51) && (devc->timebase > 0.99e-6)) {
86 /*
87 * Timebase * num hor. divs * 85(%) * 1e6(usecs) / 100
88 * -> 85 percent of sweep time
89 */
90 s = (devc->timebase * devc->model->series->num_horizontal_divs * 1000);
91 sr_spew("Sleeping for %ld usecs after trigger, "
92 "to let the acq buffer in the device fill", s);
93 g_usleep(s);
b3360671 94 }
95 }
96 if (devc->wait_status == 2) {
97 do {
98 if (time(NULL) - start >= 3) {
3e7fb88f 99 sr_dbg("Timeout waiting for trigger.");
b3360671 100 return SR_ERR_TIMEOUT;
101 }
102 if (sr_scpi_get_string(sdi->conn, ":INR?", &buf) != SR_OK)
103 return SR_ERR;
104 sr_atoi(buf, &out);
105 g_usleep(s);
106 /* XXX
107 * Now this loop condition looks suspicious! A bitwise
108 * OR of a variable and a non-zero literal should be
109 * non-zero. Logical AND of several non-zero values
110 * should be non-zero. Are many parts of the condition
111 * not taking effect? Was some different condition meant
112 * to get encoded? This needs review, and adjustment.
113 */
114 } while ((out | DEVICE_STATE_TRIG_RDY && out | DEVICE_STATE_DATA_ACQ) && out | DEVICE_STATE_STOPPED);
3e7fb88f 115 sr_dbg("Device triggerd 2.");
b3360671 116 siglent_sds_set_wait_event(devc, WAIT_NONE);
117 }
118
119 return SR_OK;
120}
121
122static int siglent_sds_trigger_wait(const struct sr_dev_inst *sdi)
123{
124 struct dev_context *devc;
125
126 if (!(devc = sdi->priv))
127 return SR_ERR;
128 return siglent_sds_event_wait(sdi);
129}
130
3e7fb88f 131/* Wait for scope to got to "Stop" in single shot mode. */
b3360671 132static int siglent_sds_stop_wait(const struct sr_dev_inst *sdi)
133{
b3360671 134 return siglent_sds_event_wait(sdi);
135}
136
137/* Send a configuration setting. */
138SR_PRIV int siglent_sds_config_set(const struct sr_dev_inst *sdi, const char *format, ...)
139{
140 va_list args;
141 int ret;
142
143 va_start(args, format);
144 ret = sr_scpi_send_variadic(sdi->conn, format, args);
145 va_end(args);
146
3e7fb88f 147 return ret;
b3360671 148}
149
3e7fb88f 150/* Start capturing a new frameset. */
b3360671 151SR_PRIV int siglent_sds_capture_start(const struct sr_dev_inst *sdi)
152{
153 struct dev_context *devc;
154
155 if (!(devc = sdi->priv))
156 return SR_ERR;
157
158 switch (devc->model->series->protocol) {
159 case SPO_MODEL:
160 if (devc->data_source == DATA_SOURCE_SCREEN) {
161 char *buf;
162 int out;
163
164 sr_dbg("Starting data capture for active frameset %" PRIu64 " of %" PRIu64,
165 devc->num_frames + 1, devc->limit_frames);
166 if (siglent_sds_config_set(sdi, "ARM") != SR_OK)
167 return SR_ERR;
168 if (sr_scpi_get_string(sdi->conn, ":INR?", &buf) != SR_OK)
169 return SR_ERR;
170 sr_atoi(buf, &out);
171 if (out == DEVICE_STATE_TRIG_RDY) {
172 siglent_sds_set_wait_event(devc, WAIT_TRIGGER);
173 } else if (out == DEVICE_STATE_TRIG_RDY + 1) {
3e7fb88f 174 sr_spew("Device triggered.");
b3360671 175 siglent_sds_set_wait_event(devc, WAIT_BLOCK);
176 return SR_OK;
177 } else {
3e7fb88f 178 sr_spew("Device did not enter ARM mode.");
b3360671 179 return SR_ERR;
180 }
3e7fb88f 181 } else { /* TODO: Implement history retrieval. */
b3360671 182 unsigned int framecount;
183 char buf[200];
184 int ret;
185
3e7fb88f 186 sr_dbg("Starting data capture for history frameset.");
b3360671 187 if (siglent_sds_config_set(sdi, "FPAR?") != SR_OK)
188 return SR_ERR;
189 ret = sr_scpi_read_data(sdi->conn, buf, 200);
190 if (ret < 0) {
191 sr_err("Read error while reading data header.");
192 return SR_ERR;
193 }
194 memcpy(&framecount, buf + 40, 4);
3e7fb88f 195 if (devc->limit_frames > framecount)
b3360671 196 sr_err("Frame limit higher that frames in buffer of device!");
3e7fb88f 197 else if (devc->limit_frames == 0)
b3360671 198 devc->limit_frames = framecount;
b3360671 199 sr_dbg("Starting data capture for history frameset %" PRIu64 " of %" PRIu64,
200 devc->num_frames + 1, devc->limit_frames);
201 if (siglent_sds_config_set(sdi, "FRAM %i", devc->num_frames + 1) != SR_OK)
202 return SR_ERR;
203 if (siglent_sds_channel_start(sdi) != SR_OK)
204 return SR_ERR;
205 siglent_sds_set_wait_event(devc, WAIT_STOP);
206 }
207 break;
208 case NON_SPO_MODEL:
209 siglent_sds_set_wait_event(devc, WAIT_TRIGGER);
210 break;
211 }
212
213 return SR_OK;
214}
215
3e7fb88f 216/* Start reading data from the current channel. */
b3360671 217SR_PRIV int siglent_sds_channel_start(const struct sr_dev_inst *sdi)
89f5fab9 218{
89f5fab9 219 struct dev_context *devc;
b3360671 220 struct sr_channel *ch;
221
222 if (!(devc = sdi->priv))
223 return SR_ERR;
224
225 ch = devc->channel_entry->data;
226
3e7fb88f 227 sr_dbg("Starting reading data from channel %d.", ch->index + 1);
b3360671 228
229 switch (devc->model->series->protocol) {
230 case NON_SPO_MODEL:
231 case SPO_MODEL:
232 if (ch->type == SR_CHANNEL_LOGIC) {
233 if (sr_scpi_send(sdi->conn, "D%d:WF?",
234 ch->index + 1) != SR_OK)
235 return SR_ERR;
236 } else {
237 if (sr_scpi_send(sdi->conn, "C%d:WF? ALL",
238 ch->index + 1) != SR_OK)
239 return SR_ERR;
240 }
241 siglent_sds_set_wait_event(devc, WAIT_NONE);
242 break;
243 }
244
245 siglent_sds_set_wait_event(devc, WAIT_BLOCK);
246
247 devc->num_channel_bytes = 0;
248 devc->num_header_bytes = 0;
249 devc->num_block_bytes = 0;
250
251 return SR_OK;
252}
253
3e7fb88f 254/* Read the header of a data block. */
b3360671 255static int siglent_sds_read_header(struct sr_dev_inst *sdi, int channelIndex)
256{
257 struct sr_scpi_dev_inst *scpi = sdi->conn;
258 struct dev_context *devc = sdi->priv;
259 char *buf = (char *)devc->buffer;
260 int ret;
261 int descLength;
3e7fb88f 262 int blockOffset = 15; /* Offset for descriptor block. */
b3360671 263 long dataLength = 0;
264
3e7fb88f
UH
265 /* Read header from device. */
266 ret = sr_scpi_read_data(scpi, buf + devc->num_header_bytes,
267 devc->model->series->buffer_samples);
b3360671 268 if (ret < 346) {
269 sr_err("Read error while reading data header.");
270 return SR_ERR;
271 }
3e7fb88f 272 sr_dbg("Device returned %i bytes.", ret);
b3360671 273 devc->num_header_bytes += ret;
3e7fb88f 274 buf += blockOffset; /* Skip to start descriptor block. */
b3360671 275
3e7fb88f
UH
276 /* Parse WaveDescriptor header. */
277 memcpy(&descLength, buf + 36, 4); /* Descriptor block length */
278 memcpy(&dataLength, buf + 60, 4); /* Data block length */
b3360671 279
280 devc->vdiv[channelIndex] = 2;
281 devc->vert_offset[channelIndex] = 0;
282 devc->blockHeaderSize = descLength + 15;
283 ret = dataLength;
3e7fb88f 284
b3360671 285 sr_dbg("Received data block header: '%s' -> block length %d", buf, ret);
3e7fb88f 286
b3360671 287 return ret;
288}
289
290SR_PRIV int siglent_sds_receive(int fd, int revents, void *cb_data)
291{
292 struct sr_dev_inst *sdi;
293 struct sr_scpi_dev_inst *scpi;
294 struct dev_context *devc;
295 struct sr_datafeed_packet packet;
296 struct sr_datafeed_analog analog;
297 struct sr_analog_encoding encoding;
298 struct sr_analog_meaning meaning;
299 struct sr_analog_spec spec;
300 struct sr_datafeed_logic logic;
301 int len, i;
302 struct sr_channel *ch;
303 gsize expected_data_bytes = 0;
304 char *memsize;
89f5fab9 305
306 (void)fd;
307
308 if (!(sdi = cb_data))
309 return TRUE;
310
311 if (!(devc = sdi->priv))
312 return TRUE;
313
b3360671 314 scpi = sdi->conn;
315
316 if (!(revents == G_IO_IN || revents == 0))
317 return TRUE;
318
319 memsize = NULL;
320 if (sr_scpi_get_string(sdi->conn, "MSIZ?", &memsize) != SR_OK)
321 return SR_ERR;
322
323 switch (devc->wait_event) {
324 case WAIT_NONE:
325 break;
326 case WAIT_TRIGGER:
327 if (siglent_sds_trigger_wait(sdi) != SR_OK)
328 return TRUE;
329 if (siglent_sds_channel_start(sdi) != SR_OK)
330 return TRUE;
331 return TRUE;
332 case WAIT_BLOCK:
333 if (siglent_sds_channel_start(sdi) != SR_OK)
334 return TRUE;
335 break;
336 case WAIT_STOP:
3e7fb88f 337 if (siglent_sds_stop_wait(sdi) != SR_OK)
b3360671 338 return TRUE;
3e7fb88f 339 if (siglent_sds_channel_start(sdi) != SR_OK)
b3360671 340 return TRUE;
b3360671 341 return TRUE;
342 default:
3e7fb88f 343 sr_err("BUG: Unknown event target encountered.");
b3360671 344 break;
345 }
346
347 ch = devc->channel_entry->data;
348
349 if (devc->num_block_bytes == 0) {
350
3e7fb88f
UH
351 if (g_ascii_strcasecmp(memsize, "14M") == 0) {
352 sr_err("Device memory depth is set to 14Mpts, so please be patient.");
353 g_usleep(4900000); /* Sleep for large memory set. */
b3360671 354 }
3e7fb88f 355 sr_dbg("New block header expected.");
b3360671 356 len = siglent_sds_read_header(sdi, ch->index);
357 expected_data_bytes = len;
358 if (len == 0)
359 /* Still reading the header. */
360 return TRUE;
361 if (len == -1) {
362 sr_err("Read error, aborting capture.");
363 packet.type = SR_DF_FRAME_END;
364 sr_session_send(sdi, &packet);
365 sdi->driver->dev_acquisition_stop(sdi);
366 return TRUE;
367 }
368
369 if (devc->data_source == DATA_SOURCE_SCREEN
370 && (unsigned)len < expected_data_bytes) {
3e7fb88f 371 sr_dbg("Discarding short data block.");
b3360671 372 sr_scpi_read_data(scpi, (char *)devc->buffer, len + 1);
373 return TRUE;
374 }
375 devc->num_block_bytes = len;
376 devc->num_block_read = 0;
377 }
378
379 len = devc->num_block_bytes - devc->num_block_read;
380 if (len > ACQ_BUFFER_SIZE)
381 len = ACQ_BUFFER_SIZE;
382
3e7fb88f 383 /* Offset the data block buffer past the IEEE header and description header. */
b3360671 384 devc->buffer += devc->blockHeaderSize;
385
386 if (len == -1) {
387 sr_err("Read error, aborting capture.");
388 packet.type = SR_DF_FRAME_END;
389 sr_session_send(sdi, &packet);
390 sdi->driver->dev_acquisition_stop(sdi);
391 return TRUE;
89f5fab9 392 }
393
b3360671 394 sr_dbg("Received %d bytes.", len);
395
396 devc->num_block_read += len;
397
398 if (ch->type == SR_CHANNEL_ANALOG) {
399 float vdiv = devc->vdiv[ch->index];
400 float offset = devc->vert_offset[ch->index];
401 GArray *float_data;
402 static GArray *data;
403 float voltage;
404 float vdivlog;
405 int digits;
406
407 data = g_array_sized_new(FALSE, FALSE, sizeof(uint8_t), len);
408 g_array_append_vals(data, devc->buffer, len);
409 float_data = g_array_new(FALSE, FALSE, sizeof(float));
410 for (i = 0; i < len; i++) {
411 voltage = (float)g_array_index(data, int8_t, i) / 25;
412 voltage = ((vdiv * voltage) - offset);
413 g_array_append_val(float_data, voltage);
414 }
415 vdivlog = log10f(vdiv);
416 digits = -(int) vdivlog + (vdivlog < 0.0);
417 sr_analog_init(&analog, &encoding, &meaning, &spec, digits);
418 analog.meaning->channels = g_slist_append(NULL, ch);
419 analog.num_samples = float_data->len;
420 analog.data = (float *)float_data->data;
421 analog.meaning->mq = SR_MQ_VOLTAGE;
422 analog.meaning->unit = SR_UNIT_VOLT;
423 analog.meaning->mqflags = 0;
424 packet.type = SR_DF_ANALOG;
425 packet.payload = &analog;
426 sr_session_send(sdi, &packet);
427 g_slist_free(analog.meaning->channels);
428 g_array_free(data, TRUE);
429 } else {
430 logic.length = len;
431 logic.unitsize = 1;
432 logic.data = devc->buffer;
433 packet.type = SR_DF_LOGIC;
434 packet.payload = &logic;
435 sr_session_send(sdi, &packet);
436 }
437
438 if (devc->num_block_read == devc->num_block_bytes) {
3e7fb88f
UH
439 sr_dbg("Block has been completed.");
440 sr_dbg("Preparing for possible next block.");
b3360671 441 devc->num_header_bytes = 0;
442 devc->num_block_bytes = 0;
3e7fb88f 443 if (devc->data_source != DATA_SOURCE_SCREEN)
b3360671 444 siglent_sds_set_wait_event(devc, WAIT_BLOCK);
b3360671 445 if (!sr_scpi_read_complete(scpi)) {
3e7fb88f 446 sr_err("Read should have been completed.");
b3360671 447 packet.type = SR_DF_FRAME_END;
448 sr_session_send(sdi, &packet);
449 sdi->driver->dev_acquisition_stop(sdi);
450 return TRUE;
451 }
452 devc->num_block_read = 0;
453 } else {
3e7fb88f 454 sr_dbg("%" PRIu64 " of %" PRIu64 " block bytes read.",
b3360671 455 devc->num_block_read, devc->num_block_bytes);
456 }
457 devc->num_channel_bytes += len;
458 if (devc->num_channel_bytes < expected_data_bytes) {
459 /* Don't have the full data for this channel yet, re-run. */
460 return TRUE;
461 }
462 if (devc->channel_entry->next) {
463 /* We got the frame for this channel, now get the next channel. */
464 devc->channel_entry = devc->channel_entry->next;
465 siglent_sds_channel_start(sdi);
466 } else {
467 /* Done with this frame. */
468 packet.type = SR_DF_FRAME_END;
469 sr_session_send(sdi, &packet);
470
471 if (++devc->num_frames == devc->limit_frames) {
472 /* Last frame, stop capture. */
473 sdi->driver->dev_acquisition_stop(sdi);
474 } else {
475 /* Get the next frame, starting with the first channel. */
476 devc->channel_entry = devc->enabled_channels;
477 siglent_sds_capture_start(sdi);
478
479 /* Start of next frame. */
480 packet.type = SR_DF_FRAME_BEGIN;
481 sr_session_send(sdi, &packet);
482 }
483 }
3e7fb88f 484
89f5fab9 485 return TRUE;
486}
b3360671 487
488SR_PRIV int siglent_sds_get_dev_cfg(const struct sr_dev_inst *sdi)
489{
490 struct dev_context *devc;
491 struct sr_channel *ch;
492 char *cmd;
493 unsigned int i;
494 int res;
495 char *response;
496 gchar **tokens;
497 int num_tokens;
498
499 devc = sdi->priv;
500
501 /* Analog channel state. */
502 for (i = 0; i < devc->model->analog_channels; i++) {
503 cmd = g_strdup_printf("C%i:TRA?", i + 1);
504 res = sr_scpi_get_bool(sdi->conn, cmd, &devc->analog_channels[i]);
505 g_free(cmd);
506 if (res != SR_OK)
507 return SR_ERR;
508 ch = g_slist_nth_data(sdi->channels, i);
509 ch->enabled = devc->analog_channels[i];
510 }
511 sr_dbg("Current analog channel state:");
512 for (i = 0; i < devc->model->analog_channels; i++)
513 sr_dbg("CH%d %s", i + 1, devc->analog_channels[i] ? "On" : "Off");
514
515 /* Digital channel state. */
516 if (devc->model->has_digital) {
517 gboolean status;
518
3e7fb88f 519 sr_dbg("Check logic analyzer channel state.");
b3360671 520 devc->la_enabled = FALSE;
521 cmd = g_strdup_printf("DGST?");
522 res = sr_scpi_get_bool(sdi->conn, cmd, &status);
523 g_free(cmd);
524 if (res != SR_OK)
525 return SR_ERR;
3e7fb88f 526 sr_dbg("Logic analyzer status: %s", status ? "On" : "Off");
b3360671 527 if (status) {
528 devc->la_enabled = TRUE;
529 for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) {
530 cmd = g_strdup_printf("D%i:DGCH?", i);
531 res = sr_scpi_get_bool(sdi->conn, cmd, &devc->digital_channels[i]);
532 g_free(cmd);
533 if (res != SR_OK)
534 return SR_ERR;
535 ch = g_slist_nth_data(sdi->channels, i + devc->model->analog_channels);
536 ch->enabled = devc->digital_channels[i];
537 sr_dbg("D%d: %s", i, devc->digital_channels[i] ? "On" : "Off");
538 }
539 } else {
540 for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) {
541 ch = g_slist_nth_data(sdi->channels, i + devc->model->analog_channels);
542 devc->digital_channels[i] = FALSE;
543 ch->enabled = devc->digital_channels[i];
544 sr_dbg("D%d: %s", i, devc->digital_channels[i] ? "On" : "Off");
545 }
546 }
547 }
548
549 /* Timebase. */
550 if (sr_scpi_get_float(sdi->conn, ":TDIV?", &devc->timebase) != SR_OK)
551 return SR_ERR;
3e7fb88f 552 sr_dbg("Current timebase: %g.", devc->timebase);
b3360671 553
554 /* Probe attenuation. */
555 for (i = 0; i < devc->model->analog_channels; i++) {
556 cmd = g_strdup_printf("C%d:ATTN?", i + 1);
557 res = sr_scpi_get_float(sdi->conn, cmd, &devc->attenuation[i]);
558 g_free(cmd);
559 if (res != SR_OK)
560 return SR_ERR;
561 }
562 sr_dbg("Current probe attenuation:");
563 for (i = 0; i < devc->model->analog_channels; i++)
564 sr_dbg("CH%d %g", i + 1, devc->attenuation[i]);
565
566 /* Vertical gain and offset. */
567 if (siglent_sds_get_dev_cfg_vertical(sdi) != SR_OK)
568 return SR_ERR;
569
570 /* Coupling. */
571 for (i = 0; i < devc->model->analog_channels; i++) {
572 cmd = g_strdup_printf("C%d:CPL?", i + 1);
573 res = sr_scpi_get_string(sdi->conn, cmd, &devc->coupling[i]);
574 g_free(cmd);
575 if (res != SR_OK)
576 return SR_ERR;
577 }
578
579 sr_dbg("Current coupling:");
580 for (i = 0; i < devc->model->analog_channels; i++)
581 sr_dbg("CH%d %s", i + 1, devc->coupling[i]);
582
583 /* Trigger source. */
584 response = NULL;
585 tokens = NULL;
586 if (sr_scpi_get_string(sdi->conn, "TRSE?", &response) != SR_OK)
587 return SR_ERR;
588 tokens = g_strsplit(response, ",", 0);
589 for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
590 if (num_tokens < 4) {
591 sr_dbg("IDN response not according to spec: %80.s.", response);
592 g_strfreev(tokens);
593 g_free(response);
594 return SR_ERR_DATA;
595 }
596 g_free(response);
597 devc->trigger_source = g_strstrip(g_strdup(tokens[2]));
3e7fb88f 598 sr_dbg("Current trigger source: %s.", devc->trigger_source);
b3360671 599
3e7fb88f 600 /* TODO: Horizontal trigger position. */
b3360671 601
602 devc->horiz_triggerpos = 0;
3e7fb88f 603 sr_dbg("Current horizontal trigger position: %g.", devc->horiz_triggerpos);
b3360671 604
605 /* Trigger slope. */
606 cmd = g_strdup_printf("%s:TRSL?", devc->trigger_source);
607 res = sr_scpi_get_string(sdi->conn, cmd, &devc->trigger_slope);
608 g_free(cmd);
609 if (res != SR_OK)
610 return SR_ERR;
3e7fb88f 611 sr_dbg("Current trigger slope: %s.", devc->trigger_slope);
b3360671 612
613 /* Trigger level. */
614 cmd = g_strdup_printf("%s:TRLV?", devc->trigger_source);
615 res = sr_scpi_get_float(sdi->conn, cmd, &devc->trigger_level);
616 g_free(cmd);
617 if (res != SR_OK)
618 return SR_ERR;
3e7fb88f 619 sr_dbg("Current trigger level: %g.", devc->trigger_level);
b3360671 620 return SR_OK;
621}
622
623SR_PRIV int siglent_sds_get_dev_cfg_vertical(const struct sr_dev_inst *sdi)
624{
625 struct dev_context *devc;
626 char *cmd;
627 unsigned int i;
628 int res;
629
630 devc = sdi->priv;
631
632 /* Vertical gain. */
633 for (i = 0; i < devc->model->analog_channels; i++) {
634 cmd = g_strdup_printf("C%d:VDIV?", i + 1);
635 res = sr_scpi_get_float(sdi->conn, cmd, &devc->vdiv[i]);
636 g_free(cmd);
637 if (res != SR_OK)
638 return SR_ERR;
639 }
640 sr_dbg("Current vertical gain:");
641 for (i = 0; i < devc->model->analog_channels; i++)
642 sr_dbg("CH%d %g", i + 1, devc->vdiv[i]);
643
644 /* Vertical offset. */
645 for (i = 0; i < devc->model->analog_channels; i++) {
646 cmd = g_strdup_printf("C%d:OFST?", i + 1);
647 res = sr_scpi_get_float(sdi->conn, cmd, &devc->vert_offset[i]);
648 g_free(cmd);
649 if (res != SR_OK)
650 return SR_ERR;
651 }
652 sr_dbg("Current vertical offset:");
653 for (i = 0; i < devc->model->analog_channels; i++)
654 sr_dbg("CH%d %g", i + 1, devc->vert_offset[i]);
655
656 return SR_OK;
657}
658
659SR_PRIV int siglent_sds_get_dev_cfg_horizontal(const struct sr_dev_inst *sdi)
660{
661 struct dev_context *devc;
662 char *cmd;
663 int res;
664 char *samplePointsString;
665 float samplerateScope;
666 float fvalue;
667 char *first, *concat;
668
669 devc = sdi->priv;
670 cmd = g_strdup_printf("SANU? C1");
671 res = sr_scpi_get_string(sdi->conn, cmd, &samplePointsString);
672 g_free(cmd);
673 if (res != SR_OK)
674 return SR_ERR;
a9a38e75 675 if (g_strstr_len(samplePointsString, -1, "Mpts") != NULL) {
b3360671 676 samplePointsString[strlen(samplePointsString) - 4] = '\0';
677
a9a38e75 678 if (g_strstr_len(samplePointsString, -1, ".") != NULL) {
b3360671 679 first = strtok(samplePointsString, ".");
680 concat = strcat(first, strtok(NULL, "."));
681 if (sr_atof_ascii(concat, &fvalue) != SR_OK || fvalue == 0.0) {
682 sr_dbg("Invalid float converted from scope response.");
683 return SR_ERR;
684 }
685 } else {
686 if (sr_atof_ascii(samplePointsString, &fvalue) != SR_OK || fvalue == 0.0) {
687 sr_dbg("Invalid float converted from scope response.");
688 return SR_ERR;
689 }
690 }
691 samplerateScope = fvalue * 100000;
692 } else {
693 samplePointsString[strlen(samplePointsString) - 4] = '\0';
694 if (sr_atof_ascii(samplePointsString, &fvalue) != SR_OK || fvalue == 0.0) {
695 sr_dbg("Invalid float converted from scope response.");
696 return SR_ERR;
697 }
698 samplerateScope = fvalue * 1000;
699 }
3e7fb88f 700 /* Get the timebase. */
b3360671 701 if (sr_scpi_get_float(sdi->conn, ":TDIV?", &devc->timebase) != SR_OK)
702 return SR_ERR;
3e7fb88f 703 sr_dbg("Current timebase: %g.", devc->timebase);
b3360671 704 devc->sampleRate = samplerateScope / (devc->timebase * devc->model->series->num_horizontal_divs);
3e7fb88f 705
b3360671 706 return SR_OK;
707}