]> sigrok.org Git - libsigrok.git/blob - src/hardware/siglent-sds/protocol.c
siglent-sds: Various cosmetics and coding-style fixes.
[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 that 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;
261         int descLength;
262         int blockOffset = 15; /* Offset for descriptor block. */
263         long dataLength = 0;
264
265         /* Read header from device. */
266         ret = sr_scpi_read_data(scpi, buf + devc->num_header_bytes,
267                 devc->model->series->buffer_samples);
268         if (ret < 346) {
269                 sr_err("Read error while reading data header.");
270                 return SR_ERR;
271         }
272         sr_dbg("Device returned %i bytes.", ret);
273         devc->num_header_bytes += ret;
274         buf += blockOffset; /* Skip to start descriptor block. */
275
276         /* Parse WaveDescriptor header. */
277         memcpy(&descLength, buf + 36, 4); /* Descriptor block length */
278         memcpy(&dataLength, buf + 60, 4); /* Data block length */
279
280         devc->vdiv[channelIndex] = 2;
281         devc->vert_offset[channelIndex] = 0;
282         devc->blockHeaderSize = descLength + 15;
283         ret = dataLength;
284
285         sr_dbg("Received data block header: '%s' -> block length %d", buf, ret);
286
287         return ret;
288 }
289
290 SR_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;
305
306         (void)fd;
307
308         if (!(sdi = cb_data))
309                 return TRUE;
310
311         if (!(devc = sdi->priv))
312                 return TRUE;
313
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:
337                 if (siglent_sds_stop_wait(sdi) != SR_OK)
338                         return TRUE;
339                 if (siglent_sds_channel_start(sdi) != SR_OK)
340                         return TRUE;
341                 return TRUE;
342         default:
343                 sr_err("BUG: Unknown event target encountered.");
344                 break;
345         }
346
347         ch = devc->channel_entry->data;
348
349         if (devc->num_block_bytes == 0) {
350
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. */
354                 }
355                 sr_dbg("New block header expected.");
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) {
371                         sr_dbg("Discarding short data block.");
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
383         /* Offset the data block buffer past the IEEE header and description header. */
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;
392         }
393
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) {
439                 sr_dbg("Block has been completed.");
440                 sr_dbg("Preparing for possible next block.");
441                 devc->num_header_bytes = 0;
442                 devc->num_block_bytes = 0;
443                 if (devc->data_source != DATA_SOURCE_SCREEN)
444                         siglent_sds_set_wait_event(devc, WAIT_BLOCK);
445                 if (!sr_scpi_read_complete(scpi)) {
446                         sr_err("Read should have been completed.");
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 {
454                 sr_dbg("%" PRIu64 " of %" PRIu64 " block bytes read.",
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         }
484
485         return TRUE;
486 }
487
488 SR_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
519                 sr_dbg("Check logic analyzer channel state.");
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;
526                 sr_dbg("Logic analyzer status: %s", status ? "On" : "Off");
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;
552         sr_dbg("Current timebase: %g.", devc->timebase);
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]));
598         sr_dbg("Current trigger source: %s.", devc->trigger_source);
599
600         /* TODO: Horizontal trigger position. */
601
602         devc->horiz_triggerpos = 0;
603         sr_dbg("Current horizontal trigger position: %g.", devc->horiz_triggerpos);
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;
611         sr_dbg("Current trigger slope: %s.", devc->trigger_slope);
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;
619         sr_dbg("Current trigger level: %g.", devc->trigger_level);
620         return SR_OK;
621 }
622
623 SR_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
659 SR_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;
675         if (g_strstr_len(samplePointsString, -1, "Mpts") != NULL) {
676                 samplePointsString[strlen(samplePointsString) - 4] = '\0';
677
678                 if (g_strstr_len(samplePointsString, -1, ".") != NULL) {
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         }
700         /* Get the timebase. */
701         if (sr_scpi_get_float(sdi->conn, ":TDIV?", &devc->timebase) != SR_OK)
702                 return SR_ERR;
703         sr_dbg("Current timebase: %g.", devc->timebase);
704         devc->sampleRate = samplerateScope / (devc->timebase * devc->model->series->num_horizontal_divs);
705
706         return SR_OK;
707 }