]> sigrok.org Git - libsigrok.git/blob - hardware/common/scpi.c
Centralise duplicated logging helper defines.
[libsigrok.git] / hardware / common / scpi.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2013 poljar (Damir Jelić) <poljarinho@gmail.com>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "libsigrok.h"
21 #include "libsigrok-internal.h"
22
23 #include <glib.h>
24 #include <string.h>
25
26 #define LOG_PREFIX "scpi"
27
28 #define SCPI_READ_RETRIES 100
29 #define SCPI_READ_RETRY_TIMEOUT 10000
30
31 /**
32  * Parse a string representation of a boolean-like value into a gboolean.
33  * Similar to sr_parse_boolstring but rejects strings which do not represent
34  * a boolean-like value.
35  *
36  * @param str String to convert.
37  * @param ret Pointer to a gboolean where the result of the conversion will be
38  * stored.
39  *
40  * @return SR_OK on success, SR_ERR on failure.
41  */
42 static int parse_strict_bool(const char *str, gboolean *ret)
43 {
44         if (!str)
45                 return SR_ERR_ARG;
46
47         if (!g_strcmp0(str, "1") ||
48             !g_ascii_strncasecmp(str, "y", 1) ||
49             !g_ascii_strncasecmp(str, "t", 1) ||
50             !g_ascii_strncasecmp(str, "yes", 3) ||
51             !g_ascii_strncasecmp(str, "true", 4) ||
52             !g_ascii_strncasecmp(str, "on", 2)) {
53                 *ret = TRUE;
54                 return SR_OK;
55         } else if (!g_strcmp0(str, "0") ||
56                    !g_ascii_strncasecmp(str, "n", 1) ||
57                    !g_ascii_strncasecmp(str, "f", 1) ||
58                    !g_ascii_strncasecmp(str, "no", 2) ||
59                    !g_ascii_strncasecmp(str, "false", 5) ||
60                    !g_ascii_strncasecmp(str, "off", 3)) {
61                 *ret = FALSE;
62                 return SR_OK;
63         }
64
65         return SR_ERR;
66 }
67
68 /**
69  * Open SCPI device.
70  *
71  * @param scpi Previously initialized SCPI device structure.
72  *
73  * @return SR_OK on success, SR_ERR on failure.
74  */
75 SR_PRIV int sr_scpi_open(struct sr_scpi_dev_inst *scpi)
76 {
77         return scpi->open(scpi->priv);
78 }
79
80 /**
81  * Add an event source for an SCPI device.
82  *
83  * @param scpi Previously initialized SCPI device structure.
84  * @param events Events to check for.
85  * @param timeout Max time to wait before the callback is called, ignored if 0.
86  * @param cb Callback function to add. Must not be NULL.
87  * @param cb_data Data for the callback function. Can be NULL.
88  *
89  * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
90  *         SR_ERR_MALLOC upon memory allocation errors.
91  */
92 SR_PRIV int sr_scpi_source_add(struct sr_scpi_dev_inst *scpi, int events,
93                 int timeout, sr_receive_data_callback_t cb, void *cb_data)
94 {
95         return scpi->source_add(scpi->priv, events, timeout, cb, cb_data);
96 }
97
98 /**
99  * Remove event source for an SCPI device.
100  *
101  * @param scpi Previously initialized SCPI device structure.
102  *
103  * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
104  *         SR_ERR_MALLOC upon memory allocation errors, SR_ERR_BUG upon
105  *         internal errors.
106  */
107 SR_PRIV int sr_scpi_source_remove(struct sr_scpi_dev_inst *scpi)
108 {
109         return scpi->source_remove(scpi->priv);
110 }
111
112 /**
113  * Send a SCPI command.
114  *
115  * @param scpi Previously initialized SCPI device structure.
116  * @param format Format string, to be followed by any necessary arguments.
117  *
118  * @return SR_OK on success, SR_ERR on failure.
119  */
120 SR_PRIV int sr_scpi_send(struct sr_scpi_dev_inst *scpi,
121                          const char *format, ...)
122 {
123         va_list args;
124         int ret;
125
126         va_start(args, format);
127         ret = sr_scpi_send_variadic(scpi, format, args);
128         va_end(args);
129
130         return ret;
131 }
132
133 /**
134  * Send a SCPI command with a variadic argument list.
135  *
136  * @param scpi Previously initialized SCPI device structure.
137  * @param format Format string.
138  * @param args Argument list.
139  *
140  * @return SR_OK on success, SR_ERR on failure.
141  */
142 SR_PRIV int sr_scpi_send_variadic(struct sr_scpi_dev_inst *scpi,
143                          const char *format, va_list args)
144 {
145         va_list args_copy;
146         char *buf;
147         int len, ret;
148
149         /* Get length of buffer required. */
150         va_copy(args_copy, args);
151         len = vsnprintf(NULL, 0, format, args_copy);
152         va_end(args_copy);
153
154         /* Allocate buffer and write out command. */
155         buf = g_malloc(len + 1);
156         vsprintf(buf, format, args);
157
158         /* Send command. */
159         ret = scpi->send(scpi->priv, buf);
160
161         /* Free command buffer. */
162         g_free(buf);
163
164         return ret;
165 }
166
167 /**
168  * Receive an SCPI reply and store the reply in scpi_response.
169  *
170  * @param scpi Previously initialised SCPI device structure.
171  * @param scpi_response Pointer where to store the SCPI response.
172  *
173  * @return SR_OK upon fetching a full SCPI response, SR_ERR upon fetching an
174  *         incomplete or no response. The allocated response must be freed by
175  *         the caller in the case of a full response as well in the case of
176  *         an incomplete.
177  */
178 SR_PRIV int sr_scpi_receive(struct sr_scpi_dev_inst *scpi,
179                         char **scpi_response)
180 {
181         return scpi->receive(scpi->priv, scpi_response);
182 }
183
184 /**
185  * Read part of a response from SCPI device.
186  *
187  * @param scpi Previously initialised SCPI device structure.
188  * @param buf Buffer to store result.
189  * @param maxlen Maximum number of bytes to read.
190  *
191  * @return Number of bytes read, or SR_ERR upon failure.
192  */
193 SR_PRIV int sr_scpi_read(struct sr_scpi_dev_inst *scpi,
194                         char *buf, int maxlen)
195 {
196         return scpi->read(scpi->priv, buf, maxlen);
197 }
198
199 /**
200  * Close SCPI device.
201  *
202  * @param scpi Previously initialized SCPI device structure.
203  *
204  * @return SR_OK on success, SR_ERR on failure.
205  */
206 SR_PRIV int sr_scpi_close(struct sr_scpi_dev_inst *scpi)
207 {
208         return scpi->close(scpi->priv);
209 }
210
211 /**
212  * Free SCPI device.
213  *
214  * @param scpi Previously initialized SCPI device structure.
215  *
216  * @return SR_OK on success, SR_ERR on failure.
217  */
218 SR_PRIV void sr_scpi_free(struct sr_scpi_dev_inst *scpi)
219 {
220         scpi->free(scpi->priv);
221         g_free(scpi);
222 }
223
224 /**
225  * Send a SCPI command, receive the reply and store the reply in scpi_response.
226  *
227  * @param scpi Previously initialised SCPI device structure.
228  * @param command The SCPI command to send to the device (can be NULL).
229  * @param scpi_response Pointer where to store the SCPI response.
230  *
231  * @return SR_OK upon fetching a full SCPI response, SR_ERR upon fetching an
232  *         incomplete or no response. The allocated response must be freed by
233  *         the caller in the case of a full response as well in the case of
234  *         an incomplete.
235  */
236 SR_PRIV int sr_scpi_get_string(struct sr_scpi_dev_inst *scpi,
237                                const char *command, char **scpi_response)
238 {
239         if (command)
240                 if (sr_scpi_send(scpi, command) != SR_OK)
241                         return SR_ERR;
242
243         return sr_scpi_receive(scpi, scpi_response);
244 }
245
246 /**
247  * Send a SCPI command, read the reply, parse it as a bool value and store the
248  * result in scpi_response.
249  *
250  * @param scpi Previously initialised SCPI device structure.
251  * @param command The SCPI command to send to the device (can be NULL).
252  * @param scpi_response Pointer where to store the parsed result.
253  *
254  * @return SR_OK on success, SR_ERR on failure.
255  */
256 SR_PRIV int sr_scpi_get_bool(struct sr_scpi_dev_inst *scpi,
257                              const char *command, gboolean *scpi_response)
258 {
259         int ret;
260         char *response;
261
262         response = NULL;
263
264         if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
265                 if (!response)
266                         return SR_ERR;
267
268         if (parse_strict_bool(response, scpi_response) == SR_OK)
269                 ret = SR_OK;
270         else
271                 ret = SR_ERR;
272
273         g_free(response);
274
275         return ret;
276 }
277
278 /**
279  * Send a SCPI command, read the reply, parse it as an integer and store the
280  * result in scpi_response.
281  *
282  * @param scpi Previously initialised SCPI device structure.
283  * @param command The SCPI command to send to the device (can be NULL).
284  * @param scpi_response Pointer where to store the parsed result.
285  *
286  * @return SR_OK on success, SR_ERR on failure.
287  */
288 SR_PRIV int sr_scpi_get_int(struct sr_scpi_dev_inst *scpi,
289                             const char *command, int *scpi_response)
290 {
291         int ret;
292         char *response;
293
294         response = NULL;
295
296         if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
297                 if (!response)
298                         return SR_ERR;
299
300         if (sr_atoi(response, scpi_response) == SR_OK)
301                 ret = SR_OK;
302         else
303                 ret = SR_ERR;
304
305         g_free(response);
306
307         return ret;
308 }
309
310 /**
311  * Send a SCPI command, read the reply, parse it as a float and store the
312  * result in scpi_response.
313  *
314  * @param scpi Previously initialised SCPI device structure.
315  * @param command The SCPI command to send to the device (can be NULL).
316  * @param scpi_response Pointer where to store the parsed result.
317  *
318  * @return SR_OK on success, SR_ERR on failure.
319  */
320 SR_PRIV int sr_scpi_get_float(struct sr_scpi_dev_inst *scpi,
321                               const char *command, float *scpi_response)
322 {
323         int ret;
324         char *response;
325
326         response = NULL;
327
328         if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
329                 if (!response)
330                         return SR_ERR;
331
332         if (sr_atof(response, scpi_response) == SR_OK)
333                 ret = SR_OK;
334         else
335                 ret = SR_ERR;
336
337         g_free(response);
338
339         return ret;
340 }
341
342 /**
343  * Send a SCPI command, read the reply, parse it as a double and store the
344  * result in scpi_response.
345  *
346  * @param scpi Previously initialised SCPI device structure.
347  * @param command The SCPI command to send to the device (can be NULL).
348  * @param scpi_response Pointer where to store the parsed result.
349  *
350  * @return SR_OK on success, SR_ERR on failure.
351  */
352 SR_PRIV int sr_scpi_get_double(struct sr_scpi_dev_inst *scpi,
353                                const char *command, double *scpi_response)
354 {
355         int ret;
356         char *response;
357
358         response = NULL;
359
360         if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
361                 if (!response)
362                         return SR_ERR;
363
364         if (sr_atod(response, scpi_response) == SR_OK)
365                 ret = SR_OK;
366         else
367                 ret = SR_ERR;
368
369         g_free(response);
370
371         return ret;
372 }
373
374 /**
375  * Send a SCPI *OPC? command, read the reply and return the result of the
376  * command.
377  *
378  * @param scpi Previously initialised SCPI device structure.
379  *
380  * @return SR_OK on success, SR_ERR on failure.
381  */
382 SR_PRIV int sr_scpi_get_opc(struct sr_scpi_dev_inst *scpi)
383 {
384         unsigned int i;
385         gboolean opc;
386
387         for (i = 0; i < SCPI_READ_RETRIES; ++i) {
388                 sr_scpi_get_bool(scpi, SCPI_CMD_OPC, &opc);
389                 if (opc)
390                         return SR_OK;
391                 g_usleep(SCPI_READ_RETRY_TIMEOUT);
392         }
393
394         return SR_ERR;
395 }
396
397 /**
398  * Send a SCPI command, read the reply, parse it as comma separated list of
399  * floats and store the as an result in scpi_response.
400  *
401  * @param scpi Previously initialised SCPI device structure.
402  * @param command The SCPI command to send to the device (can be NULL).
403  * @param scpi_response Pointer where to store the parsed result.
404  *
405  * @return SR_OK upon successfully parsing all values, SR_ERR upon a parsing
406  *         error or upon no response. The allocated response must be freed by
407  *         the caller in the case of an SR_OK as well as in the case of
408  *         parsing error.
409  */
410 SR_PRIV int sr_scpi_get_floatv(struct sr_scpi_dev_inst *scpi,
411                                const char *command, GArray **scpi_response)
412 {
413         int ret;
414         float tmp;
415         char *response;
416         gchar **ptr, **tokens;
417         GArray *response_array;
418
419         ret = SR_OK;
420         response = NULL;
421         tokens = NULL;
422
423         if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
424                 if (!response)
425                         return SR_ERR;
426
427         tokens = g_strsplit(response, ",", 0);
428         ptr = tokens;
429
430         response_array = g_array_sized_new(TRUE, FALSE, sizeof(float), 256);
431
432         while (*ptr) {
433                 if (sr_atof(*ptr, &tmp) == SR_OK)
434                         response_array = g_array_append_val(response_array,
435                                                             tmp);
436                 else
437                         ret = SR_ERR;
438
439                 ptr++;
440         }
441         g_strfreev(tokens);
442         g_free(response);
443
444         if (ret == SR_ERR && response_array->len == 0) {
445                 g_array_free(response_array, TRUE);
446                 *scpi_response = NULL;
447                 return SR_ERR;
448         }
449
450         *scpi_response = response_array;
451
452         return ret;
453 }
454
455 /**
456  * Send a SCPI command, read the reply, parse it as comma separated list of
457  * unsigned 8 bit integers and store the as an result in scpi_response.
458  *
459  * @param scpi Previously initialised SCPI device structure.
460  * @param command The SCPI command to send to the device (can be NULL).
461  * @param scpi_response Pointer where to store the parsed result.
462  *
463  * @return SR_OK upon successfully parsing all values, SR_ERR upon a parsing
464  *         error or upon no response. The allocated response must be freed by
465  *         the caller in the case of an SR_OK as well as in the case of
466  *         parsing error.
467  */
468 SR_PRIV int sr_scpi_get_uint8v(struct sr_scpi_dev_inst *scpi,
469                                const char *command, GArray **scpi_response)
470 {
471         int tmp, ret;
472         char *response;
473         gchar **ptr, **tokens;
474         GArray *response_array;
475
476         ret = SR_OK;
477         response = NULL;
478         tokens = NULL;
479
480         if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
481                 if (!response)
482                         return SR_ERR;
483
484         tokens = g_strsplit(response, ",", 0);
485         ptr = tokens;
486
487         response_array = g_array_sized_new(TRUE, FALSE, sizeof(uint8_t), 256);
488
489         while (*ptr) {
490                 if (sr_atoi(*ptr, &tmp) == SR_OK)
491                         response_array = g_array_append_val(response_array,
492                                                             tmp);
493                 else
494                         ret = SR_ERR;
495
496                 ptr++;
497         }
498         g_strfreev(tokens);
499         g_free(response);
500
501         if (response_array->len == 0) {
502                 g_array_free(response_array, TRUE);
503                 *scpi_response = NULL;
504                 return SR_ERR;
505         }
506
507         *scpi_response = response_array;
508
509         return ret;
510 }
511
512 /**
513  * Send the *IDN? SCPI command, receive the reply, parse it and store the
514  * reply as a sr_scpi_hw_info structure in the supplied scpi_response pointer.
515  *
516  * The hw_info structure must be freed by the caller via sr_scpi_hw_info_free().
517  *
518  * @param scpi Previously initialised SCPI device structure.
519  * @param scpi_response Pointer where to store the hw_info structure.
520  *
521  * @return SR_OK upon success, SR_ERR on failure.
522  */
523 SR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi,
524                               struct sr_scpi_hw_info **scpi_response)
525 {
526         int num_tokens;
527         char *response;
528         gchar **tokens;
529         struct sr_scpi_hw_info *hw_info;
530
531         response = NULL;
532         tokens = NULL;
533
534         if (sr_scpi_get_string(scpi, SCPI_CMD_IDN, &response) != SR_OK)
535                 if (!response)
536                         return SR_ERR;
537
538         /*
539          * The response to a '*IDN?' is specified by the SCPI spec. It contains
540          * a comma-separated list containing the manufacturer name, instrument
541          * model, serial number of the instrument and the firmware version.
542          */
543         tokens = g_strsplit(response, ",", 0);
544
545         for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
546
547         if (num_tokens != 4) {
548                 sr_dbg("IDN response not according to spec: %80.s.", response);
549                 g_strfreev(tokens);
550                 g_free(response);
551                 return SR_ERR;
552         }
553         g_free(response);
554
555         hw_info = g_try_malloc(sizeof(struct sr_scpi_hw_info));
556         if (!hw_info) {
557                 g_strfreev(tokens);
558                 return SR_ERR_MALLOC;
559         }
560
561         hw_info->manufacturer = g_strdup(tokens[0]);
562         hw_info->model = g_strdup(tokens[1]);
563         hw_info->serial_number = g_strdup(tokens[2]);
564         hw_info->firmware_version = g_strdup(tokens[3]);
565
566         g_strfreev(tokens);
567
568         *scpi_response = hw_info;
569
570         return SR_OK;
571 }
572
573 /**
574  * Free a sr_scpi_hw_info struct.
575  *
576  * @param hw_info Pointer to the struct to free.
577  *
578  * This function is safe to call with a NULL pointer.
579  */
580 SR_PRIV void sr_scpi_hw_info_free(struct sr_scpi_hw_info *hw_info)
581 {
582         if (hw_info) {
583                 g_free(hw_info->manufacturer);
584                 g_free(hw_info->model);
585                 g_free(hw_info->serial_number);
586                 g_free(hw_info->firmware_version);
587                 g_free(hw_info);
588         }
589 }