]> sigrok.org Git - libsigrok.git/blob - hardware/rigol-ds1xx2/protocol.c
rigol-ds1xx2: Whitespace, minor fix.
[libsigrok.git] / hardware / rigol-ds1xx2 / protocol.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
5  * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <math.h>
27 #include <glib.h>
28 #include "libsigrok.h"
29 #include "libsigrok-internal.h"
30 #include "protocol.h"
31
32 SR_PRIV int rigol_ds1xx2_receive(int fd, int revents, void *cb_data)
33 {
34         struct sr_dev_inst *sdi;
35         struct dev_context *devc;
36         struct sr_datafeed_packet packet;
37         struct sr_datafeed_analog analog;
38         unsigned char buf[WAVEFORM_SIZE];
39         double vdiv, offset;
40         float data[WAVEFORM_SIZE];
41         int probenum, len, i;
42
43         if (!(sdi = cb_data))
44                 return TRUE;
45
46         if (!(devc = sdi->priv))
47                 return TRUE;
48
49         if (revents == G_IO_IN) {
50                 len = read(fd, buf, WAVEFORM_SIZE);
51                 sr_dbg("Received %d bytes.", len);
52                 if (len == -1)
53                         return TRUE;
54
55                 if (devc->num_frame_samples == 0) {
56                         /* Start of a new frame. */
57                         packet.type = SR_DF_FRAME_BEGIN;
58                         sr_session_send(sdi, &packet);
59                 }
60
61                 probenum = devc->channel_frame->name[2] == '1' ? 0 : 1;
62                 for (i = 0; i < len; i++) {
63                         vdiv = devc->vdiv[probenum];
64                         offset = devc->vert_offset[probenum];
65                         data[i] = vdiv / 25.6 * (128 - buf[i]) - offset;
66                 }
67                 analog.probes = g_slist_append(NULL, devc->channel_frame);
68                 analog.num_samples = len;
69                 analog.data = data;
70                 analog.mq = SR_MQ_VOLTAGE;
71                 analog.unit = SR_UNIT_VOLT;
72                 analog.mqflags = 0;
73                 packet.type = SR_DF_ANALOG;
74                 packet.payload = &analog;
75                 sr_session_send(cb_data, &packet);
76                 g_slist_free(analog.probes);
77
78                 if (len != WAVEFORM_SIZE)
79                         /* Don't have the whole frame yet. */
80                         return TRUE;
81
82                 /* End of the frame. */
83                 packet.type = SR_DF_FRAME_END;
84                 sr_session_send(sdi, &packet);
85
86                 if (devc->channel_frame == devc->enabled_probes->data
87                                 && devc->enabled_probes->next != NULL) {
88                         /* We got the frame for the first channel, but
89                          * there's a second channel. */
90                         devc->channel_frame = devc->enabled_probes->next->data;
91                         rigol_ds1xx2_send(devc, ":WAV:DATA? CHAN%c",
92                                         devc->channel_frame->name[2]);
93                 } else {
94                         /* Done with both channels in this frame. */
95                         if (++devc->num_frames == devc->limit_frames) {
96                                 sdi->driver->dev_acquisition_stop(sdi, cb_data);
97                         } else {
98                                 /* Get the next frame, starting with the first channel. */
99                                 devc->channel_frame = devc->enabled_probes->data;
100                                 rigol_ds1xx2_send(devc, ":WAV:DATA? CHAN%c",
101                                                 devc->channel_frame->name[2]);
102                         }
103                 }
104         }
105
106         return TRUE;
107 }
108
109 SR_PRIV int rigol_ds1xx2_send(struct dev_context *devc, const char *format, ...)
110 {
111         va_list args;
112         char buf[256];
113         int len, out, ret;
114
115         va_start(args, format);
116         len = vsnprintf(buf, 255, format, args);
117         va_end(args);
118         strcat(buf, "\n");
119         len++;
120         out = write(devc->fd, buf, len);
121         buf[len - 1] = '\0';
122         if (out != len) {
123                 sr_dbg("Only sent %d/%d bytes of '%s'.", out, len, buf);
124                 ret = SR_ERR;
125         } else {
126                 sr_spew("Sent '%s'.", buf);
127                 ret = SR_OK;
128         }
129
130         return ret;
131 }
132
133 static int get_cfg(const struct sr_dev_inst *sdi, char *cmd, char *reply)
134 {
135         struct dev_context *devc;
136         int len;
137
138         devc = sdi->priv;
139
140         if (rigol_ds1xx2_send(devc, cmd) != SR_OK)
141                 return SR_ERR;
142
143         if ((len = read(devc->fd, reply, 255)) < 0)
144                 return SR_ERR;
145         reply[len] = '\0';
146         sr_spew("Received '%s'.", reply);
147
148         return SR_OK;
149 }
150
151 static int get_cfg_float(const struct sr_dev_inst *sdi, char *cmd, float *f)
152 {
153         char buf[256], *e;
154
155         if (get_cfg(sdi, cmd, buf) != SR_OK)
156                 return SR_ERR;
157         *f = strtof(buf, &e);
158         if (e == buf || (fpclassify(*f) & (FP_ZERO | FP_NORMAL)) == 0) {
159                 sr_dbg("failed to parse response to '%s': '%s'", cmd, buf);
160                 return SR_ERR;
161         }
162
163         return SR_OK;
164 }
165
166 static int get_cfg_string(const struct sr_dev_inst *sdi, char *cmd, char **buf)
167 {
168
169         if (!(*buf = g_try_malloc0(256)))
170                 return SR_ERR_MALLOC;
171
172         if (get_cfg(sdi, cmd, *buf) != SR_OK)
173                 return SR_ERR;
174
175         return SR_OK;
176 }
177
178 SR_PRIV int rigol_ds1xx2_get_dev_cfg(const struct sr_dev_inst *sdi)
179 {
180         struct dev_context *devc;
181         char *t_s;
182
183         devc = sdi->priv;
184
185         /* Channel state. */
186         if (get_cfg_string(sdi, ":CHAN1:DISP?", &t_s) != SR_OK)
187                 return SR_ERR;
188         devc->channels[0] = !strcmp(t_s, "ON") ? TRUE : FALSE;
189         g_free(t_s);
190         if (get_cfg_string(sdi, ":CHAN2:DISP?", &t_s) != SR_OK)
191                 return SR_ERR;
192         devc->channels[1] = !strcmp(t_s, "ON") ? TRUE : FALSE;
193         g_free(t_s);
194         sr_dbg("Current channel state CH1 %s CH2 %s",
195                         devc->channels[0] ? "on" : "off",
196                         devc->channels[1] ? "on" : "off");
197
198         /* Timebase. */
199         if (get_cfg_float(sdi, ":TIM:SCAL?", &devc->timebase) != SR_OK)
200                 return SR_ERR;
201         sr_dbg("Current timebase %f", devc->timebase);
202
203         /* Vertical gain. */
204         if (get_cfg_float(sdi, ":CHAN1:SCAL?", &devc->vdiv[0]) != SR_OK)
205                 return SR_ERR;
206         if (get_cfg_float(sdi, ":CHAN2:SCAL?", &devc->vdiv[1]) != SR_OK)
207                 return SR_ERR;
208         sr_dbg("Current vertical gain CH1 %f CH2 %f", devc->vdiv[0], devc->vdiv[1]);
209
210         /* Vertical offset. */
211         if (get_cfg_float(sdi, ":CHAN1:OFFS?", &devc->vert_offset[0]) != SR_OK)
212                 return SR_ERR;
213         if (get_cfg_float(sdi, ":CHAN2:OFFS?", &devc->vert_offset[1]) != SR_OK)
214                 return SR_ERR;
215         sr_dbg("Current vertical offset CH1 %f CH2 %f", devc->vert_offset[0],
216                         devc->vert_offset[1]);
217
218         /* Coupling. */
219         if (get_cfg_string(sdi, ":CHAN1:COUP?", &devc->coupling[0]) != SR_OK)
220                 return SR_ERR;
221         if (get_cfg_string(sdi, ":CHAN2:COUP?", &devc->coupling[1]) != SR_OK)
222                 return SR_ERR;
223         sr_dbg("Current coupling CH1 %s CH2 %s", devc->coupling[0],
224                         devc->coupling[1]);
225
226         /* Trigger source. */
227         if (get_cfg_string(sdi, ":TRIG:EDGE:SOUR?", &devc->trigger_source) != SR_OK)
228                 return SR_ERR;
229         sr_dbg("Current trigger source %s", devc->trigger_source);
230
231         /* Horizontal trigger position. */
232         if (get_cfg_float(sdi, ":TIM:OFFS?", &devc->horiz_triggerpos) != SR_OK)
233                 return SR_ERR;
234         sr_dbg("Current horizontal trigger position %f", devc->horiz_triggerpos);
235
236         /* Trigger slope. */
237         if (get_cfg_string(sdi, ":TRIG:EDGE:SLOP?", &devc->trigger_slope) != SR_OK)
238                 return SR_ERR;
239         sr_dbg("Current trigger slope %s", devc->trigger_slope);
240
241         return SR_OK;
242 }
243