]> git.zerfleddert.de Git - rigol/blame - scope.c
update to libusb-1.0
[rigol] / scope.c
CommitLineData
713be7a4
MG
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
7df76f49 4#include <stdint.h>
78fb0984
MG
5#include <string.h>
6#include <strings.h>
713be7a4 7
713be7a4 8#include "scope.h"
7906b395 9#include "usbtmc.h"
713be7a4 10
8e60ee60
MG
11#define DATASIZE 10240
12
13#define COPY_SCOPE_STRING(sc, cmd, dst) { \
14 char *buf; \
15 buf = scope_get_string(sc, cmd, sizeof(dst)); \
16 if (buf) { \
17 strcpy(dst, buf); \
18 free(buf); \
19 }\
20 }
21
713be7a4
MG
22/* Just USB for now... */
23int sendscpi(struct scope* sc, char* cmd, unsigned char *resp, int resplen)
24{
7906b395 25 return usbtmc_sendscpi(sc, cmd, resp, resplen);
713be7a4
MG
26}
27
28void closescope(struct scope* sc)
29{
7906b395 30 return usbtmc_close(sc);
713be7a4
MG
31}
32
33void claimscope(struct scope* sc)
34{
7906b395 35 return usbtmc_claim(sc);
713be7a4
MG
36}
37
38void releasescope(struct scope* sc)
39{
10ca7ea8 40 /* Disable keylock, so the user doesn't have to press the 'force'-button */
713be7a4 41 sendscpi(sc, ":KEY:LOCK DISABLE",NULL,0);
7906b395 42 return usbtmc_release(sc);
713be7a4
MG
43}
44
10ca7ea8
MG
45void resetscope(struct scope* sc)
46{
47 return usbtmc_reset(sc);
48}
49
713be7a4
MG
50struct scope* initscope(void)
51{
713be7a4
MG
52 struct scope *sc;
53
7906b395 54 sc = usbtmc_initscope();
713be7a4 55
7906b395 56 if (!sc) {
2999345d
MG
57 printf("No scope found.\n");
58 exit(EXIT_FAILURE);
59 }
713be7a4 60
713be7a4 61 claimscope(sc);
8e60ee60 62 COPY_SCOPE_STRING(sc, "*IDN?", sc->idn);
713be7a4
MG
63 releasescope(sc);
64
65 printf("Scope found (%s)\n", sc->idn);
66
67 return sc;
68}
69
70char *scope_idn(struct scope *sc)
71{
72 return sc->idn;
73}
78fb0984 74
78fb0984
MG
75char *scope_get_string(struct scope *sc, char *cmd, int maxlen)
76{
77 unsigned char *buf;
78 int res;
79
759a1836 80 buf = malloc(maxlen+1);
78fb0984
MG
81 if (buf == NULL) {
82 perror("malloc(scope_get_strings)");
83 exit(EXIT_FAILURE);
84 }
85
86 res = sendscpi(sc, cmd, buf, maxlen);
87 if (res < 0) {
88 fprintf(stderr, "Command %s failed with %d\n", cmd, res);
89 free(buf);
90 return NULL;
91 }
92
93 buf[res] = 0;
94
95 return (char*)buf;
96}
97
98int scope_get_truth_value(struct scope *sc, char *cmd)
99{
100 char buf[128];
101 int res;
102
103 bzero(buf, sizeof(buf));
104 res = sendscpi(sc, cmd, (unsigned char*)buf, sizeof(buf)-1);
105 if (res < 0) {
106 fprintf(stderr, "Command %s failed with %d\n", cmd, res);
107 return 0;
108 }
109
78fb0984
MG
110 if (strcasecmp(buf, "on") == 0) {
111 return 1;
112 } else if (strcasecmp(buf, "enable") == 0) {
113 return 1;
114 }
115
116 return 0;
117}
118
119int scope_get_int(struct scope *sc, char *cmd)
120{
121 char buf[128];
122 int res;
123
124 bzero(buf, sizeof(buf));
125 res = sendscpi(sc, cmd, (unsigned char*)buf, sizeof(buf)-1);
126 if (res < 0) {
127 fprintf(stderr, "Command %s failed with %d\n", cmd, res);
128 return 0;
129 }
130
131 return atoi(buf);
132}
133
134double scope_get_double(struct scope *sc, char*cmd)
135{
136 char buf[128];
137 int res;
138 double ret;
139
140 bzero(buf, sizeof(buf));
141 res = sendscpi(sc, cmd, (unsigned char*)buf, sizeof(buf)-1);
142 if (res < 0) {
143 fprintf(stderr, "Command %s failed with %d\n", cmd, res);
144 return 0.0;
145 }
146
147 ret = strtod(buf, NULL);
148
149 return ret;
150}
151
8e60ee60
MG
152char *scope_get_data(struct scope *sc, char *source, int *len)
153{
154 char *data = NULL;
155 char cmd[128];
156
157 if ((data = malloc(DATASIZE)) == NULL) {
158 perror("malloc");
159 return NULL;
160 }
161
162 snprintf(cmd, sizeof(cmd), ":WAV:DATA? %s", source);
163 *len = sendscpi(sc, cmd, (unsigned char*)data, DATASIZE);
164
165 return data;
166}
167
adb5a679
MG
168void update_scope_measurements(struct scope *sc)
169{
170 sc->status.measure.ch1.vpp = scope_get_double(sc, ":MEAS:VPP? CHAN1");
171 sc->status.measure.ch1.vmax = scope_get_double(sc, ":MEAS:VMAX? CHAN1");
172 sc->status.measure.ch1.vmin = scope_get_double(sc, ":MEAS:VMIN? CHAN1");
173 sc->status.measure.ch1.vamplitude = scope_get_double(sc, ":MEAS:VAMP? CHAN1");
174 sc->status.measure.ch1.vtop = scope_get_double(sc, ":MEAS:VTOP? CHAN1");
175 sc->status.measure.ch1.vbase = scope_get_double(sc, ":MEAS:VBAS? CHAN1");
176 sc->status.measure.ch1.vaverage = scope_get_double(sc, ":MEAS:VAV? CHAN1");
177 sc->status.measure.ch1.vrms = scope_get_double(sc, ":MEAS:VRMS? CHAN1");
178 sc->status.measure.ch1.overshoot = scope_get_double(sc, ":MEAS:OVER? CHAN1");
179 sc->status.measure.ch1.preshoot = scope_get_double(sc, ":MEAS:PRES? CHAN1");
180 sc->status.measure.ch1.frequency = scope_get_double(sc, ":MEAS:FREQ? CHAN1");
181 sc->status.measure.ch1.risetime = scope_get_double(sc, ":MEAS:RIS? CHAN1");
182 sc->status.measure.ch1.falltime = scope_get_double(sc, ":MEAS:FALL? CHAN1");
183 sc->status.measure.ch1.period = scope_get_double(sc, ":MEAS:PER? CHAN1");
184 sc->status.measure.ch1.pwidth = scope_get_double(sc, ":MEAS:PWID? CHAN1");
185 sc->status.measure.ch1.nwidth = scope_get_double(sc, ":MEAS:NWID? CHAN1");
186 sc->status.measure.ch1.pdutycycle = scope_get_double(sc, ":MEAS:PDUT? CHAN1");
187 sc->status.measure.ch1.ndutycycle = scope_get_double(sc, ":MEAS:NDUT? CHAN1");
188 sc->status.measure.ch1.pdelay = scope_get_double(sc, ":MEAS:PDEL? CHAN1");
189 sc->status.measure.ch1.ndelay = scope_get_double(sc, ":MEAS:NDEL? CHAN1");
190
191 sc->status.measure.ch2.vpp = scope_get_double(sc, ":MEAS:VPP? CHAN2");
192 sc->status.measure.ch2.vmax = scope_get_double(sc, ":MEAS:VMAX? CHAN2");
193 sc->status.measure.ch2.vmin = scope_get_double(sc, ":MEAS:VMIN? CHAN2");
194 sc->status.measure.ch2.vamplitude = scope_get_double(sc, ":MEAS:VAMP? CHAN2");
195 sc->status.measure.ch2.vtop = scope_get_double(sc, ":MEAS:VTOP? CHAN2");
196 sc->status.measure.ch2.vbase = scope_get_double(sc, ":MEAS:VBAS? CHAN2");
197 sc->status.measure.ch2.vaverage = scope_get_double(sc, ":MEAS:VAV? CHAN2");
198 sc->status.measure.ch2.vrms = scope_get_double(sc, ":MEAS:VRMS? CHAN2");
199 sc->status.measure.ch2.overshoot = scope_get_double(sc, ":MEAS:OVER? CHAN2");
200 sc->status.measure.ch2.preshoot = scope_get_double(sc, ":MEAS:PRES? CHAN2");
201 sc->status.measure.ch2.frequency = scope_get_double(sc, ":MEAS:FREQ? CHAN2");
202 sc->status.measure.ch2.risetime = scope_get_double(sc, ":MEAS:RIS? CHAN2");
203 sc->status.measure.ch2.falltime = scope_get_double(sc, ":MEAS:FALL? CHAN2");
204 sc->status.measure.ch2.period = scope_get_double(sc, ":MEAS:PER? CHAN2");
205 sc->status.measure.ch2.pwidth = scope_get_double(sc, ":MEAS:PWID? CHAN2");
206 sc->status.measure.ch2.nwidth = scope_get_double(sc, ":MEAS:NWID? CHAN2");
207 sc->status.measure.ch2.pdutycycle = scope_get_double(sc, ":MEAS:PDUT? CHAN2");
208 sc->status.measure.ch2.ndutycycle = scope_get_double(sc, ":MEAS:NDUT? CHAN2");
209 sc->status.measure.ch2.pdelay = scope_get_double(sc, ":MEAS:PDEL? CHAN2");
210 sc->status.measure.ch2.ndelay = scope_get_double(sc, ":MEAS:NDEL? CHAN2");
211
212 sc->status.measure.total = scope_get_truth_value(sc, ":MEAS:TOT?");
213 COPY_SCOPE_STRING(sc, ":MEAS:SOUR?", sc->status.measure.source);
214
215}
216
15747296
MG
217void update_scope_channel(struct scope *sc, int channel)
218{
219 struct channel_s *ch;
220 char cmd[128];
221 int offs;
222
223 if (channel == 1) {
224 ch = &(sc->status.channel.ch1);
225 strcpy(cmd, ":CHAN1:");
226 } else if (channel == 2) {
227 ch = &(sc->status.channel.ch2);
228 strcpy(cmd, ":CHAN2:");
229 } else {
230 fprintf(stderr, "Unknown channel %d!\n", channel);
231 return;
232 }
233
234 offs=strlen(cmd);
235
236 strcpy(cmd + offs, "BWL?"); ch->bwlimit_enabled = scope_get_truth_value(sc, cmd);
237 strcpy(cmd + offs, "COUP?"); COPY_SCOPE_STRING(sc, cmd, ch->coupling);
238 strcpy(cmd + offs, "DISP?"); ch->displayed = scope_get_truth_value(sc, cmd);
239 strcpy(cmd + offs, "INV?"); ch->inverted = scope_get_truth_value(sc, cmd);
240 strcpy(cmd + offs, "OFFS?"); ch->offset = scope_get_double(sc, cmd);
241 strcpy(cmd + offs, "PROB?"); ch->probe = scope_get_double(sc, cmd);
242 strcpy(cmd + offs, "SCAL?"); ch->scale = scope_get_double(sc, cmd);
243 strcpy(cmd + offs, "FILT?"); ch->filter_enabled = scope_get_truth_value(sc, cmd);
244 strcpy(cmd + offs, "MEMD?"); ch->memory_depth = scope_get_int(sc, cmd);
245 strcpy(cmd + offs, "VERN?"); COPY_SCOPE_STRING(sc, cmd, ch->vernier);
246}
247
78fb0984
MG
248int update_scope_status(struct scope *sc)
249{
250 bzero(&(sc->status), sizeof(sc->status));
251
252 COPY_SCOPE_STRING(sc, ":INFO:LANG?", sc->status.system.lang);
253
254 sc->status.system.counter_enabled = scope_get_truth_value(sc, ":COUN:ENAB?");
255 sc->status.system.beep_enabled = scope_get_truth_value(sc, ":BEEP:ENAB?");
256
257 sc->status.keyboard.key_lock = scope_get_truth_value(sc, ":KEY:LOCK?");
258
adb5a679
MG
259 update_scope_measurements(sc);
260
261 COPY_SCOPE_STRING(sc, ":DISP:TYPE?", sc->status.display.type);
262 COPY_SCOPE_STRING(sc, ":DISP:GRID?", sc->status.display.grid);
263 sc->status.display.persist = scope_get_truth_value(sc, ":DISP:PERS?");
264 COPY_SCOPE_STRING(sc, ":DISP:MNUD?", sc->status.display.mnudisplay);
265 sc->status.display.mnustatus = scope_get_truth_value(sc, ":DISP:MNUS?");
266 COPY_SCOPE_STRING(sc, ":DISP:SCR?", sc->status.display.screen);
267 sc->status.display.brightness = scope_get_int(sc, ":DISP:BRIG?");
268 sc->status.display.intensity = scope_get_int(sc, ":DISP:INT?");
269
15747296
MG
270 update_scope_channel(sc, 1);
271 update_scope_channel(sc, 2);
272
78fb0984
MG
273 COPY_SCOPE_STRING(sc, ":ACQ:TYPE?", sc->status.acquire.type);
274 COPY_SCOPE_STRING(sc, ":ACQ:MODE?", sc->status.acquire.mode);
275
276 sc->status.acquire.averages = scope_get_int(sc, ":ACQ:AVER?");
adb5a679
MG
277 sc->status.acquire.srate_ch1 = scope_get_double(sc, ":ACQ:SAMP? CHAN1");
278 sc->status.acquire.srate_ch2 = scope_get_double(sc, ":ACQ:SAMP? CHAN2");
78fb0984
MG
279 sc->status.acquire.srate_digital = scope_get_double(sc, ":ACQ:SAMP? DIGITAL");
280
281 COPY_SCOPE_STRING(sc, ":TIM:MODE?", sc->status.timebase.mode);
282 sc->status.timebase.offset = scope_get_double(sc, ":TIM:OFFS?");
283 sc->status.timebase.delayed_offset = scope_get_double(sc, ":TIM:DEL:OFFS?");
284 sc->status.timebase.scale = scope_get_double(sc, ":TIM:SCAL?");
285 COPY_SCOPE_STRING(sc, ":TIM:FORM?", sc->status.timebase.format);
286
811f1259
MG
287 sc->status.math.displayed = scope_get_truth_value(sc, ":MATH:DISP?");
288 sc->status.fft.displayed = scope_get_truth_value(sc, ":FFT:DISP?");
289
78fb0984
MG
290 return 0;
291}
Impressum, Datenschutz