]> sigrok.org Git - libsigrok.git/blob - src/hardware/siglent-sds/protocol.c
siglent-sds: Replace non-portable strcasestr() with g_strstr_len().
[libsigrok.git] / src / hardware / siglent-sds / protocol.c
1 /*
2  * This file is part of the libsigrok project.
3  *
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>
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
26 #define _GNU_SOURCE
27
28 #include <config.h>
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"
44 #include "protocol.h"
45
46 /* Set the next event to wait for in siglent_sds_receive */
47 static 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  */
62 static 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
128 static 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 */
138 static 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. */
145 SR_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 */
162 SR_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 */
229 SR_PRIV int siglent_sds_channel_start(const struct sr_dev_inst *sdi)
230 {
231         struct dev_context *devc;
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 */
267 static 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
299 SR_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;
314
315         (void)fd;
316
317         if (!(sdi = cb_data))
318                 return TRUE;
319
320         if (!(devc = sdi->priv))
321                 return TRUE;
322
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;
403         }
404
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         }
497         return TRUE;
498 }
499
500 SR_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
635 SR_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
671 SR_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 (g_strstr_len(samplePointsString, -1, "Mpts") != NULL) {
688                 samplePointsString[strlen(samplePointsString) - 4] = '\0';
689
690                 if (g_strstr_len(samplePointsString, -1, ".") != 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 }