uni-t-ut181a: implement device driver for the UNI-T UT181A multimeter
[libsigrok.git] / src / hardware / uni-t-ut181a / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2019-2020 Gerhard Sittig <gerhard.sittig@gmx.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 <config.h>
21 #include "protocol.h"
22
23 static const uint32_t scanopts[] = {
24         SR_CONF_CONN,
25         SR_CONF_SERIALCOMM,
26 };
27
28 static const uint32_t drvopts[] = {
29         SR_CONF_MULTIMETER,
30         SR_CONF_THERMOMETER, /* Supports two temperature probes and diffs. */
31 };
32
33 static const uint32_t devopts[] = {
34         SR_CONF_CONN | SR_CONF_GET,
35         SR_CONF_CONTINUOUS,
36         SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
37         SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
38         SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
39         SR_CONF_DATA_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
40         SR_CONF_DATALOG | SR_CONF_GET,
41         SR_CONF_MEASURED_QUANTITY | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
42         SR_CONF_RANGE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
43 };
44
45 static const char *channel_names[] = {
46         [UT181A_CH_MAIN] = "P1",
47         [UT181A_CH_AUX1] = "P2",
48         [UT181A_CH_AUX2] = "P3",
49         [UT181A_CH_AUX3] = "P4",
50         [UT181A_CH_BAR] = "bar",
51 #if UT181A_WITH_TIMESTAMP
52         [UT181A_CH_TIME] = "TS",
53 #endif
54 };
55
56 /*
57  * (Re-)retrieve the list of recordings and their names. These can change
58  * without the driver's being aware, the set is under user control.
59  *
60  * TODO Need to re-allocate the list of recording names when a larger
61  * recordings count is seen than previously allocated? This implementation
62  * assumes a known maximum number of recordings, the manual is vague on
63  * these limits.
64  */
65 static int ut181a_update_recordings(const struct sr_dev_inst *sdi)
66 {
67         struct dev_context *devc;
68         struct sr_serial_dev_inst *serial;
69         size_t rec_count, rec_idx;
70         int ret;
71
72         if (!sdi)
73                 return SR_ERR_ARG;
74         devc = sdi->priv;
75         serial = sdi->conn;
76
77         ret = ut181a_send_cmd_get_recs_count(serial);
78         if (ret < 0)
79                 return ret;
80         ret = ut181a_configure_waitfor(devc, FALSE, 0, 0,
81                 FALSE, TRUE, FALSE, FALSE);
82         if (ret < 0)
83                 return ret;
84         ret = ut181a_waitfor_response(sdi, 100);
85         if (ret < 0)
86                 return ret;
87
88         rec_count = devc->wait_state.data_value;
89         if (rec_count > ARRAY_SIZE(devc->record_names))
90                 rec_count = ARRAY_SIZE(devc->record_names);
91         for (rec_idx = 0; rec_idx < rec_count; rec_idx++) {
92                 devc->info.rec_info.rec_idx = rec_idx;
93                 ret = ut181a_send_cmd_get_rec_info(serial, rec_idx);
94                 if (ret < 0)
95                         return ret;
96                 ret = ut181a_configure_waitfor(devc,
97                         FALSE, CMD_CODE_GET_REC_INFO, 0,
98                         FALSE, FALSE, FALSE, FALSE);
99                 if (ret < 0)
100                         return ret;
101                 ret = ut181a_waitfor_response(sdi, 100);
102                 if (ret < 0)
103                         return ret;
104         }
105         devc->record_count = rec_count;
106         devc->data_source_count = DATA_SOURCE_REC_FIRST + devc->record_count;
107
108         return SR_OK;
109 }
110
111 /*
112  * Retrieve the device's current state. Run monitor mode for some time
113  * until the 'mode' (meter's current function) became available. There
114  * is no other way of querying the meter's current state.
115  */
116 static int ut181a_query_initial_state(struct sr_dev_inst *sdi, int timeout_ms)
117 {
118         struct dev_context *devc;
119         struct sr_serial_dev_inst *serial;
120         gint64 deadline;
121         int ret;
122
123         if (!sdi)
124                 return SR_ERR_ARG;
125         devc = sdi->priv;
126         serial = sdi->conn;
127
128         devc->info.meas_head.mode = 0;
129         ret = ut181a_send_cmd_monitor(serial, TRUE);
130         if (ret < 0)
131                 return ret;
132         ret = ut181a_configure_waitfor(devc, FALSE, 0, 0,
133                 TRUE, FALSE, FALSE, FALSE);
134         if (ret < 0)
135                 return ret;
136         deadline = g_get_monotonic_time();
137         deadline += timeout_ms * 1000;
138         while (1) {
139                 ret = ut181a_waitfor_response(sdi, 100);
140                 if (ret < 0)
141                         return ret;
142                 if (devc->info.meas_head.mode)
143                         break;
144                 if (g_get_monotonic_time() >= deadline)
145                         return SR_ERR_DATA;
146         }
147         (void)ut181a_send_cmd_monitor(serial, FALSE);
148         ret = ut181a_configure_waitfor(devc, TRUE, 0, 0,
149                 FALSE, FALSE, FALSE, FALSE);
150         if (ret < 0)
151                 return ret;
152         (void)ut181a_waitfor_response(sdi, 100);
153
154         return SR_OK;
155 }
156
157 static GSList *scan(struct sr_dev_driver *di, GSList *options)
158 {
159         const char *conn, *serialcomm;
160         struct sr_config *src;
161         GSList *l, *devices;
162         struct sr_serial_dev_inst *serial;
163         int ret;
164         char conn_id[64];
165         struct sr_dev_inst *sdi;
166         struct dev_context *devc;
167         size_t idx, ds_idx;
168
169         /*
170          * Implementor's note:
171          * Do _not_ add a default conn value here. Always expect users to
172          * specify the connection. Never match in the absence of a user spec.
173          *
174          * Motivation: There is no way to identify the DMM itself. Neither
175          * are the cable nor its chip unique to the device. They are not even
176          * specific to the series or the vendor. The DMM ships with a generic
177          * CP2110 USB-to-UART bridge. Attempts to auto probe will disturb
178          * other types of devices which may be attached to the probed conn.
179          *
180          * On the other hand it's perfectly fine to communicate to the
181          * device and assume that the device model will accept the requests,
182          * once the user specified the connection (and the driver), and thus
183          * instructed this driver to start such activity.
184          */
185         conn = NULL;
186         serialcomm = "9600/8n1";
187         for (l = options; l; l = l->next) {
188                 src = l->data;
189                 switch (src->key) {
190                 case SR_CONF_CONN:
191                         conn = g_variant_get_string(src->data, NULL);
192                         break;
193                 case SR_CONF_SERIALCOMM:
194                         serialcomm = g_variant_get_string(src->data, NULL);
195                         break;
196                 }
197         }
198         if (!conn)
199                 return NULL;
200
201         devices = NULL;
202         serial = sr_serial_dev_inst_new(conn, serialcomm);
203         ret = serial_open(serial, SERIAL_RDWR);
204         snprintf(conn_id, sizeof(conn_id), "%s", serial->port);
205         serial_flush(serial);
206         /*
207          * We cannot identify the device at this point in time.
208          * Successful open shall suffice for now. More activity
209          * will communicate to the device later, after the driver
210          * instance got created. See below for details.
211          */
212         if (ret != SR_OK) {
213                 serial_close(serial);
214                 sr_serial_dev_inst_free(serial);
215                 return devices;
216         }
217
218         sdi = g_malloc0(sizeof(*sdi));
219         sdi->status = SR_ST_INACTIVE;
220         sdi->vendor = g_strdup("UNI-T");
221         sdi->model = g_strdup("UT181A");
222         sdi->inst_type = SR_INST_SERIAL;
223         sdi->conn = serial;
224         sdi->connection_id = g_strdup(conn_id);
225         devc = g_malloc0(sizeof(*devc));
226         sdi->priv = devc;
227         sr_sw_limits_init(&devc->limits);
228         for (idx = 0; idx < ARRAY_SIZE(channel_names); idx++) {
229                 sr_channel_new(sdi, idx, SR_CHANNEL_ANALOG, TRUE,
230                         channel_names[idx]);
231         }
232
233         /*
234          * Run monitor mode for a while to determine the current state
235          * of the device (which cannot get queried by other means). This
236          * also deals with devices which happen to already be in monitor
237          * mode when we connect to them. As a byproduct this query drains
238          * potentially pending RX data, before getting recording details.
239          */
240         devc->disable_feed = 1;
241         ret = ut181a_query_initial_state(sdi, 2000);
242         if (ret < 0) {
243                 serial_close(serial);
244                 sr_serial_dev_inst_free(serial);
245                 return devices;
246         }
247
248         /*
249          * Number of recordings and their names are dynamic and under
250          * the user's control. Prepare for a maximum number of string
251          * labels, and fetch (and re-fetch) their names and current
252          * count on demand.
253          */
254         devc->data_source_names[DATA_SOURCE_LIVE] = "Live";
255         devc->data_source_names[DATA_SOURCE_SAVE] = "Save";
256         for (idx = 0; idx < MAX_REC_COUNT; idx++) {
257                 ds_idx = DATA_SOURCE_REC_FIRST + idx;
258                 devc->data_source_names[ds_idx] = &devc->record_names[idx][0];
259         }
260         devc->data_source_count = DATA_SOURCE_REC_FIRST;
261         ret = ut181a_update_recordings(sdi);
262         devc->data_source_count = DATA_SOURCE_REC_FIRST + devc->record_count;
263         if (ret < 0) {
264                 serial_close(serial);
265                 sr_serial_dev_inst_free(serial);
266                 return devices;
267         }
268
269         devc->disable_feed = 0;
270         serial_close(serial);
271
272         devices = g_slist_append(devices, sdi);
273
274         return std_scan_complete(di, devices);
275 }
276
277 static int config_get(uint32_t key, GVariant **data,
278         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
279 {
280         struct dev_context *devc;
281         const struct mqopt_item *mqitem;
282         GVariant *arr[2];
283         const char *range;
284
285         (void)cg;
286
287         devc = sdi->priv;
288         switch (key) {
289         case SR_CONF_CONN:
290                 *data = g_variant_new_string(sdi->connection_id);
291                 break;
292         case SR_CONF_LIMIT_FRAMES:
293         case SR_CONF_LIMIT_SAMPLES:
294         case SR_CONF_LIMIT_MSEC:
295                 if (!devc)
296                         return SR_ERR_ARG;
297                 return sr_sw_limits_config_get(&devc->limits, key, data);
298         case SR_CONF_DATA_SOURCE:
299                 if (!devc)
300                         return SR_ERR_ARG;
301                 *data = g_variant_new_string(devc->data_source_names[devc->data_source]);
302                 break;
303         case SR_CONF_DATALOG:
304                 if (!devc)
305                         return SR_ERR_ARG;
306                 *data = g_variant_new_boolean(devc->is_recording ? TRUE : FALSE);
307                 break;
308         case SR_CONF_MEASURED_QUANTITY:
309                 if (!devc)
310                         return SR_ERR_ARG;
311                 mqitem = ut181a_get_mqitem_from_mode(devc->info.meas_head.mode);
312                 if (!mqitem)
313                         return SR_ERR_NA;
314                 arr[0] = g_variant_new_uint32(mqitem->mq);
315                 arr[1] = g_variant_new_uint64(mqitem->mqflags);
316                 *data = g_variant_new_tuple(arr, ARRAY_SIZE(arr));
317                 break;
318         case SR_CONF_RANGE:
319                 if (!devc)
320                         return SR_ERR_ARG;
321                 range = ut181a_get_range_from_packet_bytes(devc);
322                 if (!range || !*range)
323                         return SR_ERR_NA;
324                 *data = g_variant_new_string(range);
325                 break;
326         default:
327                 return SR_ERR_NA;
328         }
329
330         return SR_OK;
331 }
332
333 static int config_set(uint32_t key, GVariant *data,
334         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
335 {
336         struct dev_context *devc;
337         ssize_t idx;
338         GVariant *tuple_child;
339         enum sr_mq mq;
340         enum sr_mqflag mqflags;
341         uint16_t mode;
342         int ret;
343         size_t rec_no;
344         const char *range;
345
346         (void)cg;
347
348         devc = sdi->priv;
349         switch (key) {
350         case SR_CONF_LIMIT_FRAMES:
351         case SR_CONF_LIMIT_SAMPLES:
352         case SR_CONF_LIMIT_MSEC:
353                 if (!devc)
354                         return SR_ERR_ARG;
355                 return sr_sw_limits_config_set(&devc->limits, key, data);
356         case SR_CONF_DATA_SOURCE:
357                 if (!devc)
358                         return SR_ERR_ARG;
359                 /* Prefer data source names for the lookup. */
360                 idx = std_str_idx(data, devc->data_source_names, devc->data_source_count);
361                 if (idx >= 0) {
362                         devc->data_source = idx;
363                         break;
364                 }
365                 /*
366                  * Support record number (1-based) as a fallback. The DMM
367                  * "supports" ambiguous recording names (keeps offering a
368                  * previously stored name for each new recording, neither
369                  * automatically increments nor suggests timestamps).
370                  */
371                 if (sr_atoi(g_variant_get_string(data, NULL), &ret) != SR_OK)
372                         return SR_ERR_ARG;
373                 if (ret <= 0)
374                         return SR_ERR_ARG;
375                 rec_no = ret;
376                 if (rec_no > devc->record_count)
377                         return SR_ERR_ARG;
378                 devc->data_source = DATA_SOURCE_REC_FIRST + rec_no - 1;
379                 break;
380         case SR_CONF_MEASURED_QUANTITY:
381                 if (!devc)
382                         return SR_ERR_ARG;
383                 tuple_child = g_variant_get_child_value(data, 0);
384                 mq = g_variant_get_uint32(tuple_child);
385                 g_variant_unref(tuple_child);
386                 tuple_child = g_variant_get_child_value(data, 1);
387                 mqflags = g_variant_get_uint64(tuple_child);
388                 g_variant_unref(tuple_child);
389                 mode = ut181a_get_mode_from_mq_flags(mq, mqflags);
390                 if (!mode)
391                         return SR_ERR_NA;
392                 ret = ut181a_send_cmd_setmode(sdi->conn, mode);
393                 if (ret < 0)
394                         return ret;
395                 ret = ut181a_waitfor_response(sdi->conn, 100);
396                 if (ret < 0)
397                         return ret;
398                 if (devc->info.rsp_head.rsp_type != RSP_TYPE_REPLY_CODE)
399                         return SR_ERR_DATA;
400                 if (!devc->info.reply_code.ok)
401                         return SR_ERR_DATA;
402                 break;
403         case SR_CONF_RANGE:
404                 range = g_variant_get_string(data, NULL);
405                 return ut181a_set_range_from_text(sdi, range);
406         default:
407                 return SR_ERR_NA;
408         }
409
410         return SR_OK;
411 }
412
413 static int config_list(uint32_t key, GVariant **data,
414         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
415 {
416         struct dev_context *devc;
417         int ret;
418
419         devc = sdi ? sdi->priv : NULL;
420         switch (key) {
421         case SR_CONF_SCAN_OPTIONS:
422         case SR_CONF_DEVICE_OPTIONS:
423                 return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
424         case SR_CONF_DATA_SOURCE:
425                 if (!devc)
426                         return SR_ERR_NA;
427                 ret = ut181a_update_recordings(sdi);
428                 if (ret < 0)
429                         return ret;
430                 *data = g_variant_new_strv(devc->data_source_names, devc->data_source_count);
431                 break;
432         case SR_CONF_MEASURED_QUANTITY:
433                 *data = ut181a_get_mq_flags_list();
434                 break;
435         case SR_CONF_RANGE:
436                 *data = ut181a_get_ranges_list();
437                 break;
438         default:
439                 return SR_ERR_NA;
440         }
441
442         return SR_OK;
443 }
444
445 static int dev_acquisition_start(const struct sr_dev_inst *sdi)
446 {
447         struct dev_context *devc;
448         struct sr_serial_dev_inst *serial;
449         int ret;
450         size_t rec_idx;
451
452         devc = sdi->priv;
453         serial = sdi->conn;
454         serial_flush(serial);
455
456         /*
457          * Send an acquisition start command which depends on the
458          * currently selected data source. Enter monitor mode for
459          * Live readings, get saved or recorded data otherwise. The
460          * latter require queries for sample counts, then run chunked
461          * download sequences (single item for Save, set of samples
462          * for Recordings).
463          */
464         if (devc->data_source == DATA_SOURCE_LIVE) {
465                 ret = ut181a_send_cmd_monitor(serial, TRUE);
466         } else if (devc->data_source == DATA_SOURCE_SAVE) {
467                 /*
468                  * There is only one sequence of saved measurements in
469                  * the device, but its length is yet unknown. Determine
470                  * the number of saved items, and initiate the reception
471                  * of the first value. Completion of data reception will
472                  * drive subsequent progress.
473                  */
474                 ret = ut181a_send_cmd_get_save_count(serial);
475                 if (ret < 0)
476                         return ret;
477                 ret = ut181a_configure_waitfor(devc, FALSE, 0, 0,
478                         FALSE, FALSE, TRUE, FALSE);
479                 if (ret < 0)
480                         return ret;
481                 ret = ut181a_waitfor_response(sdi, 200);
482                 if (ret < 0)
483                         return ret;
484                 devc->info.save_info.save_count = devc->wait_state.data_value;
485                 devc->info.save_info.save_idx = 0;
486                 ret = ut181a_send_cmd_get_saved_value(serial, 0);
487         } else if (devc->data_source >= DATA_SOURCE_REC_FIRST) {
488                 /*
489                  * When we get here, the data source got selected, which
490                  * includes an update of the device's list of recordings.
491                  * So the index should be good, just the number of samples
492                  * in that recording is yet unknown. Get the sample count
493                  * and initiate the reception of the first chunk, completed
494                  * reception of a chunk advances through the sequence.
495                  */
496                 rec_idx = devc->data_source - DATA_SOURCE_REC_FIRST;
497                 if (rec_idx >= devc->record_count)
498                         return SR_ERR_DATA;
499                 devc->info.rec_info.rec_count = devc->record_count;
500                 devc->info.rec_info.rec_idx = rec_idx;
501                 devc->info.rec_info.auto_next = 0;
502                 devc->info.rec_info.auto_feed = 1;
503                 ret = ut181a_send_cmd_get_rec_info(serial, rec_idx);
504                 if (ret < 0)
505                         return ret;
506                 ret = ut181a_configure_waitfor(devc,
507                         FALSE, CMD_CODE_GET_REC_INFO, 0,
508                         FALSE, FALSE, FALSE, FALSE);
509                 if (ret < 0)
510                         return ret;
511                 ret = ut181a_waitfor_response(sdi, 200);
512                 if (ret < 0)
513                         return ret;
514                 devc->info.rec_data.samples_total = devc->wait_state.data_value;
515                 devc->info.rec_data.samples_curr = 0;
516                 ret = ut181a_send_cmd_get_rec_samples(serial, rec_idx, 0);
517         }
518         if (ret < 0)
519                 return ret;
520
521         sr_sw_limits_acquisition_start(&devc->limits);
522         devc->recv_count = 0;
523         std_session_send_df_header(sdi);
524
525         serial_source_add(sdi->session, serial, G_IO_IN, 10,
526                 ut181a_handle_events, (void *)sdi);
527
528         return SR_OK;
529 }
530
531 static int dev_acquisition_stop(struct sr_dev_inst *sdi)
532 {
533
534         sdi->status = SR_ST_STOPPING;
535         /* Initiate stop here. Activity happens in ut181a_handle_events(). */
536
537         return SR_OK;
538 }
539
540 static struct sr_dev_driver uni_t_ut181a_driver_info = {
541         .name = "uni-t-ut181a",
542         .longname = "UNI-T UT181A",
543         .api_version = 1,
544         .init = std_init,
545         .cleanup = std_cleanup,
546         .scan = scan,
547         .dev_list = std_dev_list,
548         .dev_clear = std_dev_clear,
549         .config_get = config_get,
550         .config_set = config_set,
551         .config_list = config_list,
552         .dev_open = std_serial_dev_open,
553         .dev_close = std_serial_dev_close,
554         .dev_acquisition_start = dev_acquisition_start,
555         .dev_acquisition_stop = dev_acquisition_stop,
556         .context = NULL,
557 };
558 SR_REGISTER_DEV_DRIVER(uni_t_ut181a_driver_info);