]> sigrok.org Git - libsigrok.git/blob - src/hardware/siglent-sds/protocol.c
523b93f4bd056a9b0b0398c5ed3c7c064f146915
[libsigrok.git] / src / hardware / siglent-sds / protocol.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2016 mhooijboer <marchelh@gmail.com>
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>
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
23 #define _GNU_SOURCE
24
25 #include <config.h>
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>
36 #include <libsigrok/libsigrok.h>
37 #include "libsigrok-internal.h"
38 #include "scpi.h"
39 #include "protocol.h"
40
41 /* Set the next event to wait for in siglent_sds_receive(). */
42 static void siglent_sds_set_wait_event(struct dev_context *devc, enum wait_events event)
43 {
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  */
56 static 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
69         s = 10000; /* Sleep time for status refresh. */
70         if (devc->wait_status == 1) {
71                 do {
72                         if (time(NULL) - start >= 3) {
73                                 sr_dbg("Timeout waiting for trigger.");
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);
82
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);
94                 }
95         }
96         if (devc->wait_status == 2) {
97                 do {
98                         if (time(NULL) - start >= 3) {
99                                 sr_dbg("Timeout waiting for trigger.");
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);
115                 sr_dbg("Device triggerd 2.");
116                 siglent_sds_set_wait_event(devc, WAIT_NONE);
117         }
118
119         return SR_OK;
120 }
121
122 static 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
131 /* Wait for scope to got to "Stop" in single shot mode. */
132 static int siglent_sds_stop_wait(const struct sr_dev_inst *sdi)
133 {
134         return siglent_sds_event_wait(sdi);
135 }
136
137 /* Send a configuration setting. */
138 SR_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
147         return ret;
148 }
149
150 /* Start capturing a new frameset. */
151 SR_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) {
174                                 sr_spew("Device triggered.");
175                                 siglent_sds_set_wait_event(devc, WAIT_BLOCK);
176                                 return SR_OK;
177                         } else {
178                                 sr_spew("Device did not enter ARM mode.");
179                                 return SR_ERR;
180                         }
181                 } else { /* TODO: Implement history retrieval. */
182                         unsigned int framecount;
183                         char buf[200];
184                         int ret;
185
186                         sr_dbg("Starting data capture for history frameset.");
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);
195                         if (devc->limit_frames > framecount)
196                                 sr_err("Frame limit higher than frames in buffer of device!");
197                         else if (devc->limit_frames == 0)
198                                 devc->limit_frames = framecount;
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
216 /* Start reading data from the current channel. */
217 SR_PRIV int siglent_sds_channel_start(const struct sr_dev_inst *sdi)
218 {
219         struct dev_context *devc;
220         struct sr_channel *ch;
221
222         if (!(devc = sdi->priv))
223                 return SR_ERR;
224
225         ch = devc->channel_entry->data;
226
227         sr_dbg("Starting reading data from channel %d.", ch->index + 1);
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
254 /* Read the header of a data block. */
255 static 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, desc_length;
261         int block_offset = 15; /* Offset for descriptor block. */
262         long dataLength = 0;
263
264         /* Read header from device. */
265         ret = sr_scpi_read_data(scpi, buf + devc->num_header_bytes,
266                 devc->model->series->buffer_samples);
267         if (ret < 346) {
268                 sr_err("Read error while reading data header.");
269                 return SR_ERR;
270         }
271         sr_dbg("Device returned %i bytes.", ret);
272         devc->num_header_bytes += ret;
273         buf += block_offset; /* Skip to start descriptor block. */
274
275         /* Parse WaveDescriptor header. */
276         memcpy(&desc_length, buf + 36, 4); /* Descriptor block length */
277         memcpy(&dataLength, buf + 60, 4); /* Data block length */
278
279         devc->vdiv[channelIndex] = 2;
280         devc->vert_offset[channelIndex] = 0;
281         devc->block_header_size = desc_length + 15;
282         ret = dataLength;
283
284         sr_dbg("Received data block header: '%s' -> block length %d.", buf, ret);
285
286         return ret;
287 }
288
289 SR_PRIV int siglent_sds_receive(int fd, int revents, void *cb_data)
290 {
291         struct sr_dev_inst *sdi;
292         struct sr_scpi_dev_inst *scpi;
293         struct dev_context *devc;
294         struct sr_datafeed_packet packet;
295         struct sr_datafeed_analog analog;
296         struct sr_analog_encoding encoding;
297         struct sr_analog_meaning meaning;
298         struct sr_analog_spec spec;
299         struct sr_datafeed_logic logic;
300         int len, i;
301         struct sr_channel *ch;
302         gsize expected_data_bytes = 0;
303         char *memsize;
304
305         (void)fd;
306
307         if (!(sdi = cb_data))
308                 return TRUE;
309
310         if (!(devc = sdi->priv))
311                 return TRUE;
312
313         scpi = sdi->conn;
314
315         if (!(revents == G_IO_IN || revents == 0))
316                 return TRUE;
317
318         memsize = NULL;
319         if (sr_scpi_get_string(sdi->conn, "MSIZ?", &memsize) != SR_OK)
320                 return SR_ERR;
321
322         switch (devc->wait_event) {
323         case WAIT_NONE:
324                 break;
325         case WAIT_TRIGGER:
326                 if (siglent_sds_trigger_wait(sdi) != SR_OK)
327                         return TRUE;
328                 if (siglent_sds_channel_start(sdi) != SR_OK)
329                         return TRUE;
330                 return TRUE;
331         case WAIT_BLOCK:
332                 if (siglent_sds_channel_start(sdi) != SR_OK)
333                         return TRUE;
334                 break;
335         case WAIT_STOP:
336                 if (siglent_sds_stop_wait(sdi) != SR_OK)
337                         return TRUE;
338                 if (siglent_sds_channel_start(sdi) != SR_OK)
339                         return TRUE;
340                 return TRUE;
341         default:
342                 sr_err("BUG: Unknown event target encountered.");
343                 break;
344         }
345
346         ch = devc->channel_entry->data;
347
348         if (devc->num_block_bytes == 0) {
349
350                 if (g_ascii_strcasecmp(memsize, "14M") == 0) {
351                         sr_err("Device memory depth is set to 14Mpts, so please be patient.");
352                         g_usleep(4900000); /* Sleep for large memory set. */
353                 }
354                 sr_dbg("New block header expected.");
355                 len = siglent_sds_read_header(sdi, ch->index);
356                 expected_data_bytes = len;
357                 if (len == 0)
358                         /* Still reading the header. */
359                         return TRUE;
360                 if (len == -1) {
361                         sr_err("Read error, aborting capture.");
362                         packet.type = SR_DF_FRAME_END;
363                         sr_session_send(sdi, &packet);
364                         sdi->driver->dev_acquisition_stop(sdi);
365                         return TRUE;
366                 }
367
368                 if (devc->data_source == DATA_SOURCE_SCREEN
369                         && (unsigned)len < expected_data_bytes) {
370                         sr_dbg("Discarding short data block.");
371                         sr_scpi_read_data(scpi, (char *)devc->buffer, len + 1);
372                         return TRUE;
373                 }
374                 devc->num_block_bytes = len;
375                 devc->num_block_read = 0;
376         }
377
378         len = devc->num_block_bytes - devc->num_block_read;
379         if (len > ACQ_BUFFER_SIZE)
380                 len = ACQ_BUFFER_SIZE;
381
382         /* Offset the data block buffer past the IEEE header and description header. */
383         devc->buffer += devc->block_header_size;
384
385         if (len == -1) {
386                 sr_err("Read error, aborting capture.");
387                 packet.type = SR_DF_FRAME_END;
388                 sr_session_send(sdi, &packet);
389                 sdi->driver->dev_acquisition_stop(sdi);
390                 return TRUE;
391         }
392
393         sr_dbg("Received %d bytes.", len);
394
395         devc->num_block_read += len;
396
397         if (ch->type == SR_CHANNEL_ANALOG) {
398                 float vdiv = devc->vdiv[ch->index];
399                 float offset = devc->vert_offset[ch->index];
400                 GArray *float_data;
401                 static GArray *data;
402                 float voltage, vdivlog;
403                 int digits;
404
405                 data = g_array_sized_new(FALSE, FALSE, sizeof(uint8_t), len);
406                 g_array_append_vals(data, devc->buffer, len);
407                 float_data = g_array_new(FALSE, FALSE, sizeof(float));
408                 for (i = 0; i < len; i++) {
409                         voltage = (float)g_array_index(data, int8_t, i) / 25;
410                         voltage = ((vdiv * voltage) - offset);
411                         g_array_append_val(float_data, voltage);
412                 }
413                 vdivlog = log10f(vdiv);
414                 digits = -(int) vdivlog + (vdivlog < 0.0);
415                 sr_analog_init(&analog, &encoding, &meaning, &spec, digits);
416                 analog.meaning->channels = g_slist_append(NULL, ch);
417                 analog.num_samples = float_data->len;
418                 analog.data = (float *)float_data->data;
419                 analog.meaning->mq = SR_MQ_VOLTAGE;
420                 analog.meaning->unit = SR_UNIT_VOLT;
421                 analog.meaning->mqflags = 0;
422                 packet.type = SR_DF_ANALOG;
423                 packet.payload = &analog;
424                 sr_session_send(sdi, &packet);
425                 g_slist_free(analog.meaning->channels);
426                 g_array_free(data, TRUE);
427         } else {
428                 logic.length = len;
429                 logic.unitsize = 1;
430                 logic.data = devc->buffer;
431                 packet.type = SR_DF_LOGIC;
432                 packet.payload = &logic;
433                 sr_session_send(sdi, &packet);
434         }
435
436         if (devc->num_block_read == devc->num_block_bytes) {
437                 sr_dbg("Block has been completed.");
438                 sr_dbg("Preparing for possible next block.");
439                 devc->num_header_bytes = 0;
440                 devc->num_block_bytes = 0;
441                 if (devc->data_source != DATA_SOURCE_SCREEN)
442                         siglent_sds_set_wait_event(devc, WAIT_BLOCK);
443                 if (!sr_scpi_read_complete(scpi)) {
444                         sr_err("Read should have been completed.");
445                         packet.type = SR_DF_FRAME_END;
446                         sr_session_send(sdi, &packet);
447                         sdi->driver->dev_acquisition_stop(sdi);
448                         return TRUE;
449                 }
450                 devc->num_block_read = 0;
451         } else {
452                 sr_dbg("%" PRIu64 " of %" PRIu64 " block bytes read.",
453                         devc->num_block_read, devc->num_block_bytes);
454         }
455         devc->num_channel_bytes += len;
456         if (devc->num_channel_bytes < expected_data_bytes) {
457                 /* Don't have the full data for this channel yet, re-run. */
458                 return TRUE;
459         }
460         if (devc->channel_entry->next) {
461                 /* We got the frame for this channel, now get the next channel. */
462                 devc->channel_entry = devc->channel_entry->next;
463                 siglent_sds_channel_start(sdi);
464         } else {
465                 /* Done with this frame. */
466                 packet.type = SR_DF_FRAME_END;
467                 sr_session_send(sdi, &packet);
468
469                 if (++devc->num_frames == devc->limit_frames) {
470                         /* Last frame, stop capture. */
471                         sdi->driver->dev_acquisition_stop(sdi);
472                 } else {
473                         /* Get the next frame, starting with the first channel. */
474                         devc->channel_entry = devc->enabled_channels;
475                         siglent_sds_capture_start(sdi);
476
477                         /* Start of next frame. */
478                         packet.type = SR_DF_FRAME_BEGIN;
479                         sr_session_send(sdi, &packet);
480                 }
481         }
482
483         return TRUE;
484 }
485
486 SR_PRIV int siglent_sds_get_dev_cfg(const struct sr_dev_inst *sdi)
487 {
488         struct dev_context *devc;
489         struct sr_channel *ch;
490         char *cmd, *response;
491         unsigned int i;
492         int res, num_tokens;
493         gchar **tokens;
494
495         devc = sdi->priv;
496
497         /* Analog channel state. */
498         for (i = 0; i < devc->model->analog_channels; i++) {
499                 cmd = g_strdup_printf("C%i:TRA?", i + 1);
500                 res = sr_scpi_get_bool(sdi->conn, cmd, &devc->analog_channels[i]);
501                 g_free(cmd);
502                 if (res != SR_OK)
503                         return SR_ERR;
504                 ch = g_slist_nth_data(sdi->channels, i);
505                 ch->enabled = devc->analog_channels[i];
506         }
507         sr_dbg("Current analog channel state:");
508         for (i = 0; i < devc->model->analog_channels; i++)
509                 sr_dbg("CH%d %s", i + 1, devc->analog_channels[i] ? "On" : "Off");
510
511         /* Digital channel state. */
512         if (devc->model->has_digital) {
513                 gboolean status;
514
515                 sr_dbg("Check logic analyzer channel state.");
516                 devc->la_enabled = FALSE;
517                 cmd = g_strdup_printf("DGST?");
518                 res = sr_scpi_get_bool(sdi->conn, cmd, &status);
519                 g_free(cmd);
520                 if (res != SR_OK)
521                         return SR_ERR;
522                 sr_dbg("Logic analyzer status: %s", status ? "On" : "Off");
523                 if (status) {
524                         devc->la_enabled = TRUE;
525                         for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) {
526                                 cmd = g_strdup_printf("D%i:DGCH?", i);
527                                 res = sr_scpi_get_bool(sdi->conn, cmd, &devc->digital_channels[i]);
528                                 g_free(cmd);
529                                 if (res != SR_OK)
530                                         return SR_ERR;
531                                 ch = g_slist_nth_data(sdi->channels, i + devc->model->analog_channels);
532                                 ch->enabled = devc->digital_channels[i];
533                                 sr_dbg("D%d: %s", i, devc->digital_channels[i] ? "On" : "Off");
534                         }
535                 } else {
536                         for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) {
537                                 ch = g_slist_nth_data(sdi->channels, i + devc->model->analog_channels);
538                                 devc->digital_channels[i] = FALSE;
539                                 ch->enabled = devc->digital_channels[i];
540                                 sr_dbg("D%d: %s", i, devc->digital_channels[i] ? "On" : "Off");
541                         }
542                 }
543         }
544
545         /* Timebase. */
546         if (sr_scpi_get_float(sdi->conn, ":TDIV?", &devc->timebase) != SR_OK)
547                 return SR_ERR;
548         sr_dbg("Current timebase: %g.", devc->timebase);
549
550         /* Probe attenuation. */
551         for (i = 0; i < devc->model->analog_channels; i++) {
552                 cmd = g_strdup_printf("C%d:ATTN?", i + 1);
553                 res = sr_scpi_get_float(sdi->conn, cmd, &devc->attenuation[i]);
554                 g_free(cmd);
555                 if (res != SR_OK)
556                         return SR_ERR;
557         }
558         sr_dbg("Current probe attenuation:");
559         for (i = 0; i < devc->model->analog_channels; i++)
560                 sr_dbg("CH%d %g", i + 1, devc->attenuation[i]);
561
562         /* Vertical gain and offset. */
563         if (siglent_sds_get_dev_cfg_vertical(sdi) != SR_OK)
564                 return SR_ERR;
565
566         /* Coupling. */
567         for (i = 0; i < devc->model->analog_channels; i++) {
568                 cmd = g_strdup_printf("C%d:CPL?", i + 1);
569                 res = sr_scpi_get_string(sdi->conn, cmd, &devc->coupling[i]);
570                 g_free(cmd);
571                 if (res != SR_OK)
572                         return SR_ERR;
573         }
574
575         sr_dbg("Current coupling:");
576         for (i = 0; i < devc->model->analog_channels; i++)
577                 sr_dbg("CH%d %s", i + 1, devc->coupling[i]);
578
579         /* Trigger source. */
580         response = NULL;
581         tokens = NULL;
582         if (sr_scpi_get_string(sdi->conn, "TRSE?", &response) != SR_OK)
583                 return SR_ERR;
584         tokens = g_strsplit(response, ",", 0);
585         for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
586         if (num_tokens < 4) {
587                 sr_dbg("IDN response not according to spec: %80.s.", response);
588                 g_strfreev(tokens);
589                 g_free(response);
590                 return SR_ERR_DATA;
591         }
592         g_free(response);
593         devc->trigger_source = g_strstrip(g_strdup(tokens[2]));
594         sr_dbg("Current trigger source: %s.", devc->trigger_source);
595
596         /* TODO: Horizontal trigger position. */
597
598         devc->horiz_triggerpos = 0;
599         sr_dbg("Current horizontal trigger position: %g.", devc->horiz_triggerpos);
600
601         /* Trigger slope. */
602         cmd = g_strdup_printf("%s:TRSL?", devc->trigger_source);
603         res = sr_scpi_get_string(sdi->conn, cmd, &devc->trigger_slope);
604         g_free(cmd);
605         if (res != SR_OK)
606                 return SR_ERR;
607         sr_dbg("Current trigger slope: %s.", devc->trigger_slope);
608
609         /* Trigger level. */
610         cmd = g_strdup_printf("%s:TRLV?", devc->trigger_source);
611         res = sr_scpi_get_float(sdi->conn, cmd, &devc->trigger_level);
612         g_free(cmd);
613         if (res != SR_OK)
614                 return SR_ERR;
615         sr_dbg("Current trigger level: %g.", devc->trigger_level);
616         return SR_OK;
617 }
618
619 SR_PRIV int siglent_sds_get_dev_cfg_vertical(const struct sr_dev_inst *sdi)
620 {
621         struct dev_context *devc;
622         char *cmd;
623         unsigned int i;
624         int res;
625
626         devc = sdi->priv;
627
628         /* Vertical gain. */
629         for (i = 0; i < devc->model->analog_channels; i++) {
630                 cmd = g_strdup_printf("C%d:VDIV?", i + 1);
631                 res = sr_scpi_get_float(sdi->conn, cmd, &devc->vdiv[i]);
632                 g_free(cmd);
633                 if (res != SR_OK)
634                         return SR_ERR;
635         }
636         sr_dbg("Current vertical gain:");
637         for (i = 0; i < devc->model->analog_channels; i++)
638                 sr_dbg("CH%d %g", i + 1, devc->vdiv[i]);
639
640         /* Vertical offset. */
641         for (i = 0; i < devc->model->analog_channels; i++) {
642                 cmd = g_strdup_printf("C%d:OFST?", i + 1);
643                 res = sr_scpi_get_float(sdi->conn, cmd, &devc->vert_offset[i]);
644                 g_free(cmd);
645                 if (res != SR_OK)
646                         return SR_ERR;
647         }
648         sr_dbg("Current vertical offset:");
649         for (i = 0; i < devc->model->analog_channels; i++)
650                 sr_dbg("CH%d %g", i + 1, devc->vert_offset[i]);
651
652         return SR_OK;
653 }
654
655 SR_PRIV int siglent_sds_get_dev_cfg_horizontal(const struct sr_dev_inst *sdi)
656 {
657         struct dev_context *devc;
658         char *cmd;
659         int res;
660         char *sample_points_string;
661         float samplerate_scope, fvalue;
662         char *first, *concat;
663
664         devc = sdi->priv;
665         cmd = g_strdup_printf("SANU? C1");
666         res = sr_scpi_get_string(sdi->conn, cmd, &sample_points_string);
667         g_free(cmd);
668         if (res != SR_OK)
669                 return SR_ERR;
670         if (g_strstr_len(sample_points_string, -1, "Mpts") != NULL) {
671                 sample_points_string[strlen(sample_points_string) - 4] = '\0';
672
673                 if (g_strstr_len(sample_points_string, -1, ".") != NULL) {
674                         first = strtok(sample_points_string, ".");
675                         concat = strcat(first, strtok(NULL, "."));
676                         if (sr_atof_ascii(concat, &fvalue) != SR_OK || fvalue == 0.0) {
677                                 sr_dbg("Invalid float converted from scope response.");
678                                 return SR_ERR;
679                         }
680                 } else {
681                         if (sr_atof_ascii(sample_points_string, &fvalue) != SR_OK || fvalue == 0.0) {
682                                 sr_dbg("Invalid float converted from scope response.");
683                                 return SR_ERR;
684                         }
685                 }
686                 samplerate_scope = fvalue * 100000;
687         } else {
688                 sample_points_string[strlen(sample_points_string) - 4] = '\0';
689                 if (sr_atof_ascii(sample_points_string, &fvalue) != SR_OK || fvalue == 0.0) {
690                         sr_dbg("Invalid float converted from scope response.");
691                         return SR_ERR;
692                 }
693                 samplerate_scope = fvalue * 1000;
694         }
695         /* Get the timebase. */
696         if (sr_scpi_get_float(sdi->conn, ":TDIV?", &devc->timebase) != SR_OK)
697                 return SR_ERR;
698         sr_dbg("Current timebase: %g.", devc->timebase);
699         devc->samplerate = samplerate_scope / (devc->timebase * devc->model->series->num_horizontal_divs);
700
701         return SR_OK;
702 }