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