]> sigrok.org Git - libsigrok.git/blob - src/scpi/scpi_libgpib.c
6b156b2cb5dfaddb88aedc75a67752ba95e208e8
[libsigrok.git] / src / scpi / scpi_libgpib.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2014 Martin Ling <martin-sigrok@earth.li>
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 <gpib/ib.h>
21 #include <string.h>
22 #include <libsigrok/libsigrok.h>
23 #include "libsigrok-internal.h"
24 #include "scpi.h"
25
26 #define LOG_PREFIX "scpi_gpib"
27
28 struct scpi_gpib {
29         char *name;
30         int descriptor;
31         int read_started;
32 };
33
34 static int scpi_gpib_dev_inst_new(void *priv, struct drv_context *drvc,
35                 const char *resource, char **params, const char *serialcomm)
36 {
37         struct scpi_gpib *gscpi = priv;
38
39         (void)drvc;
40         (void)resource;
41         (void)serialcomm;
42
43         if (!params || !params[1])
44                         return SR_ERR;
45
46         gscpi->name = g_strdup(params[1]);
47
48         return SR_OK;
49 }
50
51 static int scpi_gpib_open(void *priv)
52 {
53         struct scpi_gpib *gscpi = priv;
54
55         if ((gscpi->descriptor = ibfind(gscpi->name)) < 0)
56                 return SR_ERR;
57
58         return SR_OK;
59 }
60
61 static int scpi_gpib_source_add(struct sr_session *session, void *priv,
62                 int events, int timeout, sr_receive_data_callback cb, void *cb_data)
63 {
64         (void) priv;
65
66         /* Hook up a dummy handler to receive data from the device. */
67         return sr_session_source_add(session, -1, events, timeout, cb, cb_data);
68 }
69
70 static int scpi_gpib_source_remove(struct sr_session *session, void *priv)
71 {
72         (void) priv;
73
74         return sr_session_source_remove(session, -1);
75 }
76
77 static int scpi_gpib_send(void *priv, const char *command)
78 {
79         struct scpi_gpib *gscpi = priv;
80         int len = strlen(command);
81
82         ibwrt(gscpi->descriptor, command, len);
83
84         if (ibsta & ERR)
85         {
86                 sr_err("Error while sending SCPI command: '%s': iberr = %d.",
87                                 command, iberr);
88                 return SR_ERR;
89         }
90
91         if (ibcnt < len)
92         {
93                 sr_err("Failed to send all of SCPI command: '%s': "
94                                 "len = %d, ibcnt = .", command, len, ibcnt);
95                 return SR_ERR;
96         }
97
98         sr_spew("Successfully sent SCPI command: '%s'.", command);
99
100         return SR_OK;
101 }
102
103 static int scpi_gpib_read_begin(void *priv)
104 {
105         struct scpi_gpib *gscpi = priv;
106
107         gscpi->read_started = 0;
108
109         return SR_OK;
110 }
111
112 static int scpi_gpib_read_data(void *priv, char *buf, int maxlen)
113 {
114         struct scpi_gpib *gscpi = priv;
115
116         ibrd(gscpi->descriptor, buf, maxlen);
117
118         if (ibsta & ERR)
119         {
120                 sr_err("Error while reading SCPI response: iberr = %d.", iberr);
121                 return SR_ERR;
122         }
123
124         gscpi->read_started = 1;
125
126         return ibcnt;
127 }
128
129 static int scpi_gpib_read_complete(void *priv)
130 {
131         struct scpi_gpib *gscpi = priv;
132
133         return gscpi->read_started && (ibsta & END);
134 }
135
136 static int scpi_gpib_close(void *priv)
137 {
138         struct scpi_gpib *gscpi = priv;
139
140         ibonl(gscpi->descriptor, 0);
141
142         return SR_OK;
143 }
144
145 static void scpi_gpib_free(void *priv)
146 {
147         struct scpi_gpib *gscpi = priv;
148
149         g_free(gscpi->name);
150 }
151
152 SR_PRIV const struct sr_scpi_dev_inst scpi_libgpib_dev = {
153         .name = "GPIB",
154         .prefix = "libgpib",
155         .priv_size = sizeof(struct scpi_gpib),
156         .dev_inst_new = scpi_gpib_dev_inst_new,
157         .open = scpi_gpib_open,
158         .source_add = scpi_gpib_source_add,
159         .source_remove = scpi_gpib_source_remove,
160         .send = scpi_gpib_send,
161         .read_begin = scpi_gpib_read_begin,
162         .read_data = scpi_gpib_read_data,
163         .read_complete = scpi_gpib_read_complete,
164         .close = scpi_gpib_close,
165         .free = scpi_gpib_free,
166 };