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