]> sigrok.org Git - libsigrok.git/blob - hardware/atten-pps3xxx/api.c
atten-pps3xxx: Fix options reporting.
[libsigrok.git] / hardware / atten-pps3xxx / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2014 Bert Vermeulen <bert@biot.com>
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 <string.h>
21 #include <errno.h>
22 #include "protocol.h"
23
24 /*
25  * The default serial communication settings on the device are 9600
26  * baud, 9 data bits. The 9th bit isn't actually used, and the vendor
27  * software uses Mark parity to absorb the extra bit.
28  *
29  * Since 9 data bits is not a standard available in POSIX, we use two
30  * stop bits to skip over the extra bit instead.
31  */
32 #define SERIALCOMM "9600/8n2"
33
34 static const int32_t scanopts[] = {
35         SR_CONF_CONN,
36         SR_CONF_SERIALCOMM,
37 };
38
39 static const int32_t devopts[] = {
40         SR_CONF_POWER_SUPPLY,
41         SR_CONF_CONTINUOUS,
42         SR_CONF_OUTPUT_CHANNEL,
43         SR_CONF_OVER_CURRENT_PROTECTION,
44 };
45
46 static const int32_t devopts_pg[] = {
47         SR_CONF_OUTPUT_VOLTAGE,
48         SR_CONF_OUTPUT_VOLTAGE_MAX,
49         SR_CONF_OUTPUT_CURRENT,
50         SR_CONF_OUTPUT_CURRENT_MAX,
51         SR_CONF_OUTPUT_ENABLED,
52 };
53
54 static const char *channel_modes[] = {
55         "Independent",
56         "Series",
57         "Parallel",
58 };
59
60 static struct pps_model models[] = {
61         { PPS_3203T_3S, "PPS3203T-3S",
62                 CHANMODE_INDEPENDENT | CHANMODE_SERIES | CHANMODE_PARALLEL,
63                 3,
64                 {
65                         /* Channel 1 */
66                         { { 0, 32, 0.01 }, { 0, 3, 0.001 } },
67                         /* Channel 2 */
68                         { { 0, 32, 0.01 }, { 0, 3, 0.001 } },
69                         /* Channel 3 */
70                         { { 0, 6, 0.01 }, { 0, 3, 0.001 } },
71                 },
72         },
73 };
74
75
76 SR_PRIV struct sr_dev_driver atten_pps3203_driver_info;
77 static struct sr_dev_driver *di = &atten_pps3203_driver_info;
78
79 static int init(struct sr_context *sr_ctx)
80 {
81         return std_init(sr_ctx, di, LOG_PREFIX);
82 }
83
84 static GSList *scan(GSList *options, int modelid)
85 {
86         struct sr_dev_inst *sdi;
87         struct drv_context *drvc;
88         struct dev_context *devc;
89         struct sr_config *src;
90         struct sr_probe *probe;
91         struct sr_probe_group *pg;
92         struct sr_serial_dev_inst *serial;
93         GSList *l, *devices;
94         struct pps_model *model;
95         uint8_t packet[PACKET_SIZE];
96         unsigned int i;
97         int ret;
98         const char *conn, *serialcomm;
99         char channel[10];
100
101         devices = NULL;
102         drvc = di->priv;
103         drvc->instances = NULL;
104
105         conn = serialcomm = NULL;
106         for (l = options; l; l = l->next) {
107                 src = l->data;
108                 switch (src->key) {
109                 case SR_CONF_CONN:
110                         conn = g_variant_get_string(src->data, NULL);
111                         break;
112                 case SR_CONF_SERIALCOMM:
113                         serialcomm = g_variant_get_string(src->data, NULL);
114                         break;
115                 }
116         }
117         if (!conn)
118                 return NULL;
119         if (!serialcomm)
120                 serialcomm = SERIALCOMM;
121
122         if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
123                 return NULL;
124
125         if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
126                 return NULL;
127         serial_flush(serial);
128
129         /* This is how the vendor software probes for hardware. */
130         memset(packet, 0, PACKET_SIZE);
131         packet[0] = 0xaa;
132         packet[1] = 0xaa;
133         if (serial_write(serial, packet, PACKET_SIZE) == -1) {
134                 sr_err("Unable to write while probing for hardware: %s",
135                                 strerror(errno));
136                 return NULL;
137         }
138         /* The device responds with a 24-byte packet when it receives a packet.
139          * At 9600 baud, 300ms is long enough for it to have arrived. */
140         g_usleep(300 * 1000);
141         memset(packet, 0, PACKET_SIZE);
142         if ((ret = serial_read_nonblocking(serial, packet, PACKET_SIZE)) < 0) {
143                 sr_err("Unable to read while probing for hardware: %s",
144                                 strerror(errno));
145                 return NULL;
146         }
147         if (ret != PACKET_SIZE || packet[0] != 0xaa || packet[1] != 0xaa) {
148                 /* Doesn't look like an Atten PPS. */
149                 return NULL;
150         }
151
152         model = NULL;
153         for (i = 0; i < ARRAY_SIZE(models); i++) {
154                 if (models[i].modelid == modelid) {
155                         model = &models[i];
156                         break;
157                 }
158         }
159         if (!model) {
160                 sr_err("Unknown modelid %d", modelid);
161                 return NULL;
162         }
163
164         sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, "Atten", model->name, NULL);
165         sdi->driver = di;
166         sdi->inst_type = SR_INST_SERIAL;
167         sdi->conn = serial;
168         for (i = 0; i < MAX_CHANNELS; i++) {
169                 snprintf(channel, 10, "CH%d", i + 1);
170                 probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel);
171                 sdi->probes = g_slist_append(sdi->probes, probe);
172                 pg = g_malloc(sizeof(struct sr_probe_group));
173                 pg->name = g_strdup(channel);
174                 pg->probes = g_slist_append(NULL, probe);
175                 pg->priv = NULL;
176                 sdi->probe_groups = g_slist_append(sdi->probe_groups, pg);
177         }
178
179         devc = g_malloc0(sizeof(struct dev_context));
180         devc->model = model;
181         devc->config = g_malloc0(sizeof(struct per_channel_config) * model->num_channels);
182         sdi->priv = devc;
183         drvc->instances = g_slist_append(drvc->instances, sdi);
184         devices = g_slist_append(devices, sdi);
185
186         serial_close(serial);
187         if (!devices)
188                 sr_serial_dev_inst_free(serial);
189
190         return devices;
191 }
192
193 static GSList *scan_3203(GSList *options)
194 {
195         return scan(options, PPS_3203T_3S);
196 }
197
198 static GSList *dev_list(void)
199 {
200         return ((struct drv_context *)(di->priv))->instances;
201 }
202
203 static int dev_clear(void)
204 {
205         return std_dev_clear(di, NULL);
206 }
207
208 static int cleanup(void)
209 {
210         return dev_clear();
211 }
212
213 static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi,
214                 const struct sr_probe_group *probe_group)
215 {
216         struct dev_context *devc;
217         struct sr_probe *probe;
218         int channel, ret;
219
220         if (!sdi)
221                 return SR_ERR_ARG;
222
223         devc = sdi->priv;
224
225         ret = SR_OK;
226         if (!probe_group) {
227                 /* No probe group: global options. */
228                 switch (key) {
229                 case SR_CONF_OUTPUT_CHANNEL:
230                         *data = g_variant_new_string(channel_modes[devc->channel_mode]);
231                         break;
232                 case SR_CONF_OVER_CURRENT_PROTECTION:
233                         *data = g_variant_new_boolean(devc->over_current_protection);
234                         break;
235                 default:
236                         return SR_ERR_NA;
237                 }
238         } else {
239                 /* We only ever have one channel per probe group in this driver. */
240                 probe = probe_group->probes->data;
241                 channel = probe->index;
242
243                 switch (key) {
244                 case SR_CONF_OUTPUT_VOLTAGE:
245                         *data = g_variant_new_double(devc->config[channel].output_voltage_last);
246                         break;
247                 case SR_CONF_OUTPUT_VOLTAGE_MAX:
248                         *data = g_variant_new_double(devc->config[channel].output_voltage_max);
249                         break;
250                 case SR_CONF_OUTPUT_CURRENT:
251                         *data = g_variant_new_double(devc->config[channel].output_current_last);
252                         break;
253                 case SR_CONF_OUTPUT_CURRENT_MAX:
254                         *data = g_variant_new_double(devc->config[channel].output_current_max);
255                         break;
256                 case SR_CONF_OUTPUT_ENABLED:
257                         *data = g_variant_new_boolean(devc->config[channel].output_enabled);
258                         break;
259                 default:
260                         return SR_ERR_NA;
261                 }
262         }
263
264         return ret;
265 }
266
267 static int find_str(const char *str, const char **strings, int array_size)
268 {
269         int idx, i;
270
271         idx = -1;
272         for (i = 0; i < array_size; i++) {
273                 if (!strcmp(str, strings[i])) {
274                         idx = i;
275                         break;
276                 }
277         }
278
279         return idx;
280 }
281
282 static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi,
283                 const struct sr_probe_group *probe_group)
284 {
285         struct dev_context *devc;
286         struct sr_probe *probe;
287         gdouble dval;
288         int channel, ret, ival;
289         const char *sval;
290         gboolean bval;
291
292         if (sdi->status != SR_ST_ACTIVE)
293                 return SR_ERR_DEV_CLOSED;
294
295         ret = SR_OK;
296         devc = sdi->priv;
297         if (!probe_group) {
298                 /* No probe group: global options. */
299                 switch (key) {
300                 case SR_CONF_OUTPUT_CHANNEL:
301                         sval = g_variant_get_string(data, NULL);
302                         if ((ival = find_str(sval, channel_modes,
303                                                         ARRAY_SIZE(channel_modes))) == -1) {
304                                 ret = SR_ERR_ARG;
305                                 break;
306                         }
307                         if (devc->model->channel_modes && (1 << ival) == 0) {
308                                 /* Not supported on this model. */
309                                 ret = SR_ERR_ARG;
310                         }
311                         if (ival == devc->channel_mode_set)
312                                 /* Nothing to do. */
313                                 break;
314                         devc->channel_mode_set = ival;
315                         devc->config_dirty = TRUE;
316                         break;
317                 case SR_CONF_OVER_CURRENT_PROTECTION:
318                         bval = g_variant_get_boolean(data);
319                         if (bval == devc->over_current_protection_set)
320                                 /* Nothing to do. */
321                                 break;
322                         devc->over_current_protection_set = bval;
323                         devc->config_dirty = TRUE;
324                         break;
325                 default:
326                         return SR_ERR_NA;
327                 }
328         } else {
329                 /* Probe group specified: per-channel options. */
330                 /* We only ever have one channel per probe group in this driver. */
331                 probe = probe_group->probes->data;
332                 channel = probe->index;
333
334                 switch (key) {
335                 case SR_CONF_OUTPUT_VOLTAGE_MAX:
336                         dval = g_variant_get_double(data);
337                         if (dval < 0 || dval > devc->model->channels[channel].voltage[1])
338                                 ret = SR_ERR_ARG;
339                         devc->config[channel].output_voltage_max = dval;
340                         devc->config_dirty = TRUE;
341                         break;
342                 case SR_CONF_OUTPUT_CURRENT_MAX:
343                         dval = g_variant_get_double(data);
344                         if (dval < 0 || dval > devc->model->channels[channel].current[1])
345                                 ret = SR_ERR_ARG;
346                         devc->config[channel].output_current_max = dval;
347                         devc->config_dirty = TRUE;
348                         break;
349                 case SR_CONF_OUTPUT_ENABLED:
350                         bval = g_variant_get_boolean(data);
351                         if (bval == devc->config[channel].output_enabled_set)
352                                 /* Nothing to do. */
353                                 break;
354                         devc->config[channel].output_enabled_set = bval;
355                         devc->config_dirty = TRUE;
356                         break;
357                 default:
358                         ret = SR_ERR_NA;
359                 }
360         }
361
362
363         return ret;
364 }
365
366 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
367                 const struct sr_probe_group *probe_group)
368 {
369         struct dev_context *devc;
370         struct sr_probe *probe;
371         GVariant *gvar;
372         GVariantBuilder gvb;
373         int channel, ret, i;
374
375         /* Always available, even without sdi. */
376         if (key == SR_CONF_SCAN_OPTIONS) {
377                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
378                                 scanopts, ARRAY_SIZE(scanopts), sizeof(int32_t));
379                 return SR_OK;
380         }
381
382         if (!sdi)
383                 return SR_ERR_ARG;
384         devc = sdi->priv;
385
386         ret = SR_OK;
387         if (!probe_group) {
388                 /* No probe group: global options. */
389                 switch (key) {
390                 case SR_CONF_DEVICE_OPTIONS:
391                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
392                                         devopts, ARRAY_SIZE(devopts), sizeof(int32_t));
393                         break;
394                 case SR_CONF_OUTPUT_CHANNEL:
395                         if (devc->model->channel_modes == CHANMODE_INDEPENDENT) {
396                                 /* The 1-channel models. */
397                                 *data = g_variant_new_strv(channel_modes, 1);
398                         } else {
399                                 /* The other models support all modes. */
400                                 *data = g_variant_new_strv(channel_modes, ARRAY_SIZE(channel_modes));
401                         }
402                         break;
403                 default:
404                         return SR_ERR_NA;
405                 }
406         } else {
407                 /* Probe group specified: per-channel options. */
408                 if (!sdi)
409                         return SR_ERR_ARG;
410                 /* We only ever have one channel per probe group in this driver. */
411                 probe = probe_group->probes->data;
412                 channel = probe->index;
413
414                 switch (key) {
415                 case SR_CONF_DEVICE_OPTIONS:
416                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
417                                         devopts_pg, ARRAY_SIZE(devopts_pg), sizeof(int32_t));
418                         break;
419                 case SR_CONF_OUTPUT_VOLTAGE_MAX:
420                         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
421                         /* Min, max, step. */
422                         for (i = 0; i < 3; i++) {
423                                 gvar = g_variant_new_double(devc->model->channels[channel].voltage[i]);
424                                 g_variant_builder_add_value(&gvb, gvar);
425                         }
426                         *data = g_variant_builder_end(&gvb);
427                         break;
428                 case SR_CONF_OUTPUT_CURRENT_MAX:
429                         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
430                         /* Min, max, step. */
431                         for (i = 0; i < 3; i++) {
432                                 gvar = g_variant_new_double(devc->model->channels[channel].current[i]);
433                                 g_variant_builder_add_value(&gvb, gvar);
434                         }
435                         *data = g_variant_builder_end(&gvb);
436                         break;
437                 default:
438                         return SR_ERR_NA;
439                 }
440         }
441
442         return ret;
443 }
444
445 static int dev_close(struct sr_dev_inst *sdi)
446 {
447         struct dev_context *devc;
448
449         devc = sdi->priv;
450         if (devc->config_dirty)
451                 /* Some configuration changes were queued up but didn't
452                  * get sent to the device, likely because we were never
453                  * in acquisition mode. Send them out now. */
454                 send_config(sdi);
455
456         return std_serial_dev_close(sdi);
457 }
458
459 static int dev_acquisition_start(const struct sr_dev_inst *sdi,
460                 void *cb_data)
461 {
462         struct dev_context *devc;
463         struct sr_serial_dev_inst *serial;
464         uint8_t packet[PACKET_SIZE];
465
466         (void)cb_data;
467
468         if (sdi->status != SR_ST_ACTIVE)
469                 return SR_ERR_DEV_CLOSED;
470
471         devc = sdi->priv;
472         memset(devc->packet, 0x44, PACKET_SIZE);
473         devc->packet_size = 0;
474
475         devc->acquisition_running = TRUE;
476
477         serial = sdi->conn;
478         serial_source_add(serial, G_IO_IN, 50, atten_pps3xxx_receive_data, (void *)sdi);
479         std_session_send_df_header(cb_data, LOG_PREFIX);
480
481         /* Send a "probe" configuration packet now. */
482         memset(packet, 0, PACKET_SIZE);
483         packet[0] = 0xaa;
484         packet[1] = 0xaa;
485         send_packet(sdi, packet);
486
487         return SR_OK;
488 }
489
490 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
491 {
492         struct dev_context *devc;
493
494         (void)cb_data;
495
496         if (sdi->status != SR_ST_ACTIVE)
497                 return SR_ERR_DEV_CLOSED;
498
499         devc = sdi->priv;
500         devc->acquisition_running = FALSE;
501
502         return SR_OK;
503 }
504
505 SR_PRIV struct sr_dev_driver atten_pps3203_driver_info = {
506         .name = "atten-pps3203",
507         .longname = "Atten PPS3203T-3S",
508         .api_version = 1,
509         .init = init,
510         .cleanup = cleanup,
511         .scan = scan_3203,
512         .dev_list = dev_list,
513         .dev_clear = dev_clear,
514         .config_get = config_get,
515         .config_set = config_set,
516         .config_list = config_list,
517         .dev_open = std_serial_dev_open,
518         .dev_close = dev_close,
519         .dev_acquisition_start = dev_acquisition_start,
520         .dev_acquisition_stop = dev_acquisition_stop,
521         .priv = NULL,
522 };