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