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