]> sigrok.org Git - libsigrok.git/blob - src/hardware/yokogawa-dlm/protocol_wrappers.c
scpi-pps: don't break SCPI devices when scanning for HP-IB devices
[libsigrok.git] / src / hardware / yokogawa-dlm / protocol_wrappers.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2014 abraxa (Soeren Apel) <soeren@apelpie.net>
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 <config.h>
21 #include "protocol_wrappers.h"
22
23 #define MAX_COMMAND_SIZE 64
24
25 /*
26  * DLM2000 comm spec:
27  * https://www.yokogawa.com/pdf/provide/E/GW/IM/0000022842/0/IM710105-17E.pdf
28  */
29
30 int dlm_timebase_get(struct sr_scpi_dev_inst *scpi,
31                 gchar **response)
32 {
33         return sr_scpi_get_string(scpi, ":TIMEBASE:TDIV?", response);
34 }
35
36 int dlm_timebase_set(struct sr_scpi_dev_inst *scpi,
37                 const gchar *value)
38 {
39         gchar cmd[MAX_COMMAND_SIZE];
40         g_snprintf(cmd, sizeof(cmd), ":TIMEBASE:TDIV %s", value);
41         return sr_scpi_send(scpi, cmd);
42 }
43
44 int dlm_horiz_trigger_pos_get(struct sr_scpi_dev_inst *scpi,
45                 float *response)
46 {
47         return sr_scpi_get_float(scpi, ":TRIGGER:DELAY:TIME?", response);
48 }
49
50 int dlm_horiz_trigger_pos_set(struct sr_scpi_dev_inst *scpi,
51                 const gchar *value)
52 {
53         gchar cmd[MAX_COMMAND_SIZE];
54         g_snprintf(cmd, sizeof(cmd), ":TRIGGER:DELAY:TIME %s", value);
55         return sr_scpi_send(scpi, cmd);
56 }
57
58 int dlm_trigger_source_get(struct sr_scpi_dev_inst *scpi,
59                 gchar **response)
60 {
61         return sr_scpi_get_string(scpi, ":TRIGGER:ATRIGGER:SIMPLE:SOURCE?", response);
62 }
63
64 int dlm_trigger_source_set(struct sr_scpi_dev_inst *scpi,
65                 const gchar *value)
66 {
67         gchar cmd[MAX_COMMAND_SIZE];
68         g_snprintf(cmd, sizeof(cmd), ":TRIGGER:ATRIGGER:SIMPLE:SOURCE %s", value);
69         return sr_scpi_send(scpi, cmd);
70 }
71
72 int dlm_trigger_slope_get(struct sr_scpi_dev_inst *scpi,
73                 int *response)
74 {
75         gchar *resp;
76         int result;
77
78         result = SR_ERR;
79
80         if (sr_scpi_get_string(scpi, ":TRIGGER:ATRIGGER:SIMPLE:SLOPE?", &resp) != SR_OK) {
81                 g_free(resp);
82                 return SR_ERR;
83         }
84
85         if (strcmp("RISE", resp) == 0) {
86                 *response = SLOPE_POSITIVE;
87                 result = SR_OK;
88         }
89
90         if (strcmp("FALL", resp) == 0) {
91                 *response = SLOPE_NEGATIVE;
92                 result = SR_OK;
93         }
94
95         g_free(resp);
96
97         return result;
98 }
99
100 int dlm_trigger_slope_set(struct sr_scpi_dev_inst *scpi,
101                 const int value)
102 {
103         if (value == SLOPE_POSITIVE)
104                 return sr_scpi_send(scpi, ":TRIGGER:ATRIGGER:SIMPLE:SLOPE RISE");
105
106         if (value == SLOPE_NEGATIVE)
107                 return sr_scpi_send(scpi, ":TRIGGER:ATRIGGER:SIMPLE:SLOPE FALL");
108
109         return SR_ERR_ARG;
110 }
111
112 int dlm_analog_chan_state_get(struct sr_scpi_dev_inst *scpi, int channel,
113                 gboolean *response)
114 {
115         gchar cmd[MAX_COMMAND_SIZE];
116         g_snprintf(cmd, sizeof(cmd), ":CHANNEL%d:DISPLAY?", channel);
117         return sr_scpi_get_bool(scpi, cmd, response);
118 }
119
120 int dlm_analog_chan_state_set(struct sr_scpi_dev_inst *scpi, int channel,
121                 const gboolean value)
122 {
123         gchar cmd[MAX_COMMAND_SIZE];
124
125         if (value)
126                 g_snprintf(cmd, sizeof(cmd), ":CHANNEL%d:DISPLAY ON", channel);
127         else
128                 g_snprintf(cmd, sizeof(cmd), ":CHANNEL%d:DISPLAY OFF", channel);
129
130         return sr_scpi_send(scpi, cmd);
131 }
132
133 int dlm_analog_chan_vdiv_get(struct sr_scpi_dev_inst *scpi, int channel,
134                 gchar **response)
135 {
136         gchar cmd[MAX_COMMAND_SIZE];
137         g_snprintf(cmd, sizeof(cmd), ":CHANNEL%d:VDIV?", channel);
138         return sr_scpi_get_string(scpi, cmd, response);
139 }
140
141 int dlm_analog_chan_vdiv_set(struct sr_scpi_dev_inst *scpi, int channel,
142                 const gchar *value)
143 {
144         gchar cmd[MAX_COMMAND_SIZE];
145         g_snprintf(cmd, sizeof(cmd), ":CHANNEL%d:VDIV %s", channel, value);
146         return sr_scpi_send(scpi, cmd);
147 }
148
149 int dlm_analog_chan_voffs_get(struct sr_scpi_dev_inst *scpi, int channel,
150                 float *response)
151 {
152         gchar cmd[MAX_COMMAND_SIZE];
153         g_snprintf(cmd, sizeof(cmd), ":CHANNEL%d:POSITION?", channel);
154         return sr_scpi_get_float(scpi, cmd, response);
155 }
156
157 int dlm_analog_chan_srate_get(struct sr_scpi_dev_inst *scpi, int channel,
158                 float *response)
159 {
160         gchar cmd[MAX_COMMAND_SIZE];
161         g_snprintf(cmd, sizeof(cmd), ":WAVEFORM:TRACE %d", channel);
162
163         if (sr_scpi_send(scpi, cmd) != SR_OK)
164                 return SR_ERR;
165
166         g_snprintf(cmd, sizeof(cmd), ":WAVEFORM:RECORD 0");
167         if (sr_scpi_send(scpi, cmd) != SR_OK)
168                 return SR_ERR;
169
170         return sr_scpi_get_float(scpi, ":WAVEFORM:SRATE?", response);
171 }
172
173 int dlm_analog_chan_coupl_get(struct sr_scpi_dev_inst *scpi, int channel,
174                 gchar **response)
175 {
176         gchar cmd[MAX_COMMAND_SIZE];
177         g_snprintf(cmd, sizeof(cmd), ":CHANNEL%d:COUPLING?", channel);
178         return sr_scpi_get_string(scpi, cmd, response);
179 }
180
181 int dlm_analog_chan_coupl_set(struct sr_scpi_dev_inst *scpi, int channel,
182                 const gchar *value)
183 {
184         gchar cmd[MAX_COMMAND_SIZE];
185         g_snprintf(cmd, sizeof(cmd), ":CHANNEL%d:COUPLING %s", channel, value);
186         return sr_scpi_send(scpi, cmd);
187 }
188
189 int dlm_analog_chan_wrange_get(struct sr_scpi_dev_inst *scpi, int channel,
190                 float *response)
191 {
192         gchar cmd[MAX_COMMAND_SIZE];
193         int result;
194
195         g_snprintf(cmd, sizeof(cmd), ":WAVEFORM:TRACE %d", channel);
196         result = sr_scpi_send(scpi, cmd);
197         result &= sr_scpi_get_float(scpi, ":WAVEFORM:RANGE?", response);
198         return result;
199 }
200
201 int dlm_analog_chan_woffs_get(struct sr_scpi_dev_inst *scpi, int channel,
202                 float *response)
203 {
204         gchar cmd[MAX_COMMAND_SIZE];
205         int result;
206
207         g_snprintf(cmd, sizeof(cmd), ":WAVEFORM:TRACE %d", channel);
208         result = sr_scpi_send(scpi, cmd);
209         result &= sr_scpi_get_float(scpi, ":WAVEFORM:OFFSET?", response);
210         return result;
211 }
212
213 int dlm_digital_chan_state_get(struct sr_scpi_dev_inst *scpi, int channel,
214                 gboolean *response)
215 {
216         gchar cmd[MAX_COMMAND_SIZE];
217         g_snprintf(cmd, sizeof(cmd), ":LOGIC:PODA:BIT%d:DISPLAY?", channel);
218         return sr_scpi_get_bool(scpi, cmd, response);
219 }
220
221 int dlm_digital_chan_state_set(struct sr_scpi_dev_inst *scpi, int channel,
222                 const gboolean value)
223 {
224         gchar cmd[MAX_COMMAND_SIZE];
225
226         if (value)
227                 g_snprintf(cmd, sizeof(cmd), ":LOGIC:PODA:BIT%d:DISPLAY ON", channel);
228         else
229                 g_snprintf(cmd, sizeof(cmd), ":LOGIC:PODA:BIT%d:DISPLAY OFF", channel);
230
231         return sr_scpi_send(scpi, cmd);
232 }
233
234 int dlm_digital_pod_state_get(struct sr_scpi_dev_inst *scpi, int pod,
235                 gboolean *response)
236 {
237         gchar cmd[MAX_COMMAND_SIZE];
238
239         /* TODO: pod currently ignored as DLM2000 only has pod A. */
240         (void)pod;
241
242         g_snprintf(cmd, sizeof(cmd), ":LOGIC:MODE?");
243         return sr_scpi_get_bool(scpi, cmd, response);
244 }
245
246 int dlm_digital_pod_state_set(struct sr_scpi_dev_inst *scpi, int pod,
247                 const gboolean value)
248 {
249         /* TODO: pod currently ignored as DLM2000 only has pod A. */
250         (void)pod;
251
252         if (value)
253                 return sr_scpi_send(scpi, ":LOGIC:MODE ON");
254         else
255                 return sr_scpi_send(scpi, ":LOGIC:MODE OFF");
256 }
257
258 int dlm_response_headers_set(struct sr_scpi_dev_inst *scpi,
259                 const gboolean value)
260 {
261         if (value)
262                 return sr_scpi_send(scpi, ":COMMUNICATE:HEADER ON");
263         else
264                 return sr_scpi_send(scpi, ":COMMUNICATE:HEADER OFF");
265 }
266
267 int dlm_acquisition_stop(struct sr_scpi_dev_inst *scpi)
268 {
269         return sr_scpi_send(scpi, ":STOP");
270 }
271
272 int dlm_acq_length_get(struct sr_scpi_dev_inst *scpi,
273                 uint32_t *response)
274 {
275         int ret;
276         char *s;
277         long tmp;
278
279         if (sr_scpi_get_string(scpi, ":WAVEFORM:LENGTH?", &s) != SR_OK)
280                 if (!s)
281                         return SR_ERR;
282
283         if (sr_atol(s, &tmp) == SR_OK)
284                 ret = SR_OK;
285         else
286                 ret = SR_ERR;
287
288         g_free(s);
289         *response = tmp;
290
291         return ret;
292 }
293
294 int dlm_chunks_per_acq_get(struct sr_scpi_dev_inst *scpi, int *response)
295 {
296         int result, acq_len;
297
298         /*
299          * Data retrieval queries such as :WAVEFORM:SEND? will only return
300          * up to 12500 samples at a time. If the oscilloscope operates in a
301          * mode where more than 12500 samples fit on screen (i.e. in one
302          * acquisition), data needs to be retrieved multiple times.
303          */
304
305         result = sr_scpi_get_int(scpi, ":WAVEFORM:LENGTH?", &acq_len);
306         *response = MAX(acq_len / DLM_MAX_FRAME_LENGTH, 1);
307
308         return result;
309 }
310
311 int dlm_start_frame_set(struct sr_scpi_dev_inst *scpi, int value)
312 {
313         gchar cmd[MAX_COMMAND_SIZE];
314
315         g_snprintf(cmd, sizeof(cmd), ":WAVEFORM:START %d",
316                         value * DLM_MAX_FRAME_LENGTH);
317
318         return sr_scpi_send(scpi, cmd);
319 }
320
321 int dlm_data_get(struct sr_scpi_dev_inst *scpi, int acquisition_num)
322 {
323         gchar cmd[MAX_COMMAND_SIZE];
324
325         g_snprintf(cmd, sizeof(cmd), ":WAVEFORM:ALL:SEND? %d", acquisition_num);
326         return sr_scpi_send(scpi, cmd);
327 }
328
329 int dlm_analog_data_get(struct sr_scpi_dev_inst *scpi, int channel)
330 {
331         gchar cmd[MAX_COMMAND_SIZE];
332         int result;
333
334         result = sr_scpi_send(scpi, ":WAVEFORM:FORMAT BYTE");
335         if (result == SR_OK) result = sr_scpi_send(scpi, ":WAVEFORM:RECORD 0");
336         if (result == SR_OK) result = sr_scpi_send(scpi, ":WAVEFORM:START 0");
337         if (result == SR_OK) result = sr_scpi_send(scpi, ":WAVEFORM:END 124999999");
338
339         g_snprintf(cmd, sizeof(cmd), ":WAVEFORM:TRACE %d", channel);
340         if (result == SR_OK) result = sr_scpi_send(scpi, cmd);
341
342         if (result == SR_OK) result = sr_scpi_send(scpi, ":WAVEFORM:SEND? 1");
343
344         return result;
345 }
346
347 int dlm_digital_data_get(struct sr_scpi_dev_inst *scpi)
348 {
349         int result;
350
351         result = sr_scpi_send(scpi, ":WAVEFORM:FORMAT BYTE");
352         if (result == SR_OK) result = sr_scpi_send(scpi, ":WAVEFORM:RECORD 0");
353         if (result == SR_OK) result = sr_scpi_send(scpi, ":WAVEFORM:START 0");
354         if (result == SR_OK) result = sr_scpi_send(scpi, ":WAVEFORM:END 124999999");
355         if (result == SR_OK) result = sr_scpi_send(scpi, ":WAVEFORM:TRACE LOGIC");
356         if (result == SR_OK) result = sr_scpi_send(scpi, ":WAVEFORM:SEND? 1");
357
358         return result;
359 }