]> sigrok.org Git - libsigrok.git/blob - src/dmm/eev121gw.c
Backport recent changes from mainline.
[libsigrok.git] / src / dmm / eev121gw.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2018 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 2 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 /**
21  * @file
22  *
23  * EEVblog 121GW 19-bytes binary protocol parser.
24  *
25  * @internal
26  *
27  * Note that this protocol is different from other meters. We need not
28  * decode the LCD presentation (segments a-g and dot of seven segment
29  * displays). Neither need we decode a textual presentation consisting
30  * of number strings with decimals, and scale/quantity suffixes. Instead
31  * a binary packet is received which contains an unsigned mantissa for
32  * the value, and a number of boolean flags as well as bitfields for modes
33  * and ranges.
34  *
35  * But the protocol is also similar to the four-display variant of the
36  * metex14 protocol. A single DMM packet contains information for two
37  * displays and a bargraph, as well as several flags corresponding to
38  * display indicators and global device state. The vendor's documentation
39  * refers to these sections as "main", "sub", "bar", and "icon".
40  *
41  * It's essential to understand that the serial-dmm API is only able to
42  * communicate a single float value (including its precision and quantity
43  * details) in a single parse call. Which is why we keep a channel index
44  * in the 'info' structure, and run the parse routine several times upon
45  * reception of a single packet. This approach is shared with the metex14
46  * parser.
47  *
48  * The parse routine here differs from other DMM parsers which typically
49  * are split into routines which parse a value (get a number and exponent),
50  * parse flags, and handle flags which were parsed before. The 121GW
51  * meter's packets don't fit this separation naturally, getting the value
52  * and related flags heavily depends on which display shall get inspected,
53  * thus should be done at the same time. Filling in an 'info' structure
54  * from packet content first, and mapping this 'info' to the 'analog'
55  * details then still is very useful for maintainability.
56  *
57  * TODO:
58  * - The meter is feature packed. This implementation does support basic
59  *   operation (voltage, current, power, resistance, continuity, diode,
60  *   capacitance, temperature). Support for remaining modes, previously
61  *   untested ranges, and advanced features (DC+AC, VA power, dB gain,
62  *   burden voltage) may be missing or incomplete. Ranges support and
63  *   value scaling should be considered "under development" in general
64  *   until test coverage was increased. Some flags are not evaluated
65  *   correctly yet, or not at all (min/max/avg, memory).
66  * - Test previously untested modes: current, power, gain, sub display
67  *   modes. Test untested ranges (voltage above 30V, temperature above
68  *   30deg (into the hundreds), negative temperatures, large resistors,
69  *   large capacitors). Test untested features (min/max/avg, 1ms peak,
70  *   log memory).
71  * - It's assumed that a continuous data stream was arranged for. This
72  *   implementation does not support the "packet request" API. Also I
73  *   was to understand that once the request was sent (write 0300 to
74  *   handle 9, after connecting) no further request is needed. Only
75  *   the loss of communication may need recovery, which we leave as an
76  *   option for later improvement, or as a feature of an external helper
77  *   which feeds the COM port from Bluetooth communication data, or
78  *   abstracts away the BLE communication.
79  *
80  * Implementation notes:
81  * - Yes some ranges seem duplicate but that's fine. The meter's packets
82  *   do provide multiple range indices for some of the modes which do
83  *   communicate values in the same range of values.
84  * - Some of the packet's bits don't match the available documentation.
85  *   Some of the meter's features are not available to the PC side by
86  *   means of inspecting packets.
87  *   - Bit 5 of "bar value" was seen with value 1 in FREQ and OHM:
88  *     f2  17 84 21 21  08 00 00 00  64 01 01 17  12 37  02 40 00  7d
89  *     So we keep the test around but accept when it fails.
90  *   - The "gotta beep" activity of continuity/break test mode is not
91  *     available in the packets.
92  * - The interpretation of range indices depends on the specific mode
93  *   (meter's function, and range when selectable by the user like mV).
94  *   As does the precision of results.
95  */
96
97 #include "config.h"
98 #include <ctype.h>
99 #include <glib.h>
100 #include <math.h>
101 #include <string.h>
102 #include <strings.h>
103 #include "libsigrok/libsigrok.h"
104 #include "libsigrok-internal.h"
105
106 #define LOG_PREFIX "eev121gw"
107
108 /*
109  * TODO:
110  * When these bit field extraction helpers move to some common location,
111  * their names may need adjustment to reduce the potential for conflicts.
112  */
113 // #define BIT(n) (1UL << (n))
114 #define MASK(len) ((1UL << (len)) - 1)
115 #define FIELD_PL(v, pos, len) (((v) >> (pos)) & MASK(len))
116 #define FIELD_NL(v, name) FIELD_PL(v, POS_ ## name, LEN_ ## name)
117 #define FIELD_NB(v, name) FIELD_PL(v, POS_ ## name, 1)
118
119 /*
120  * Support compile time checks for expected sizeof() results etc, like
121  *   STATIC_ASSERT(sizeof(struct packet) == 19, "packet size");
122  * Probably should go to some common location.
123  * See http://www.pixelbeat.org/programming/gcc/static_assert.html for details.
124  */
125 #define ASSERT_CONCAT_(a, b) a ## b
126 #define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
127 /* These can't be used after statements in c89. */
128 #ifdef __COUNTER__
129   #define STATIC_ASSERT(e, m) \
130     ; enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1 / (int)(!!(e)) }
131 #else
132   /*
133    * This can't be used twice on the same line so ensure if using in headers
134    * that the headers are not included twice (by wrapping in #ifndef...#endif).
135    * Note it doesn't cause an issue when used on same line of separate modules
136    * compiled with gcc -combine -fwhole-program.
137    */
138   #define STATIC_ASSERT(e, m) \
139     ; enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1 / (int)(!!(e)) }
140 #endif
141
142 /*
143  * Symbolic identifiers for access to the packet's payload. "Offsets"
144  * address bytes within the packet. "Positions" specify the (lowest)
145  * bit number of a field, "lengths" specify the fields' number of bits.
146  * "Values" specify magic values or fixed content (SBZ, RSV, etc).
147  */
148 enum eev121gw_packet_offs {
149         OFF_START_CMD,
150 #define  VAL_START_CMD          0xf2
151         OFF_SERIAL_3,
152         OFF_SERIAL_2,
153         OFF_SERIAL_1,
154         OFF_SERIAL_0,
155 #define  POS_SERIAL_YEAR        24
156 #define  LEN_SERIAL_YEAR        8
157 #define  POS_SERIAL_MONTH       20
158 #define  LEN_SERIAL_MONTH       4
159 #define  POS_SERIAL_NUMBER      0
160 #define  LEN_SERIAL_NUMBER      20
161         OFF_MAIN_MODE,
162 #define  POS_MAIN_MODE_VAL_U    6
163 #define  LEN_MAIN_MODE_VAL_U    2
164 #define  POS_MAIN_MODE_RSV_5    5
165 #define  POS_MAIN_MODE_MODE     0
166 #define  LEN_MAIN_MODE_MODE     5
167         OFF_MAIN_RANGE,
168 #define  POS_MAIN_RANGE_OFL     7
169 #define  POS_MAIN_RANGE_SIGN    6
170 #define  POS_MAIN_RANGE_DEGC    5
171 #define  POS_MAIN_RANGE_DEGF    4
172 #define  POS_MAIN_RANGE_RANGE   0
173 #define  LEN_MAIN_RANGE_RANGE   4
174         OFF_MAIN_VAL_H,
175         OFF_MAIN_VAL_L,
176         OFF_SUB_MODE,
177 #define  POS_SUB_MODE_MODE      0
178 #define  LEN_SUB_MODE_MODE      8
179         OFF_SUB_RANGE,
180 #define  POS_SUB_RANGE_OFL      7
181 #define  POS_SUB_RANGE_SIGN     6
182 #define  POS_SUB_RANGE_K        5
183 #define  POS_SUB_RANGE_HZ       4
184 #define  POS_SUB_RANGE_RSV_3    3
185 #define  POS_SUB_RANGE_POINT    0
186 #define  LEN_SUB_RANGE_POINT    3
187         OFF_SUB_VAL_H,
188         OFF_SUB_VAL_L,
189         OFF_BAR_STATUS,
190 #define  POS_BAR_STATUS_RSV_5   5
191 #define  LEN_BAR_STATUS_RSV_5   3
192 #define  POS_BAR_STATUS_USE     4
193 #define  POS_BAR_STATUS_150     3
194 #define  POS_BAR_STATUS_SIGN    2
195 #define  POS_BAR_STATUS_1K_500  0
196 #define  LEN_BAR_STATUS_1K_500  2
197         OFF_BAR_VALUE,
198 #define  POS_BAR_VALUE_RSV_6    6
199 #define  LEN_BAR_VALUE_RSV_6    2
200 #define  POS_BAR_VALUE_RSV_5    5
201 #define  POS_BAR_VALUE_VALUE    0
202 #define  LEN_BAR_VALUE_VALUE    5
203         OFF_ICON_STS_1,
204 #define  POS_ICON_STS1_DEGC     7
205 #define  POS_ICON_STS1_1KHZ     6
206 #define  POS_ICON_STS1_1MSPK    5
207 #define  POS_ICON_STS1_DCAC     3
208 #define  LEN_ICON_STS1_DCAC     2
209 #define  POS_ICON_STS1_AUTO     2
210 #define  POS_ICON_STS1_APO      1
211 #define  POS_ICON_STS1_BAT      0
212         OFF_ICON_STS_2,
213 #define  POS_ICON_STS2_DEGF     7
214 #define  POS_ICON_STS2_BT       6
215 #define  POS_ICON_STS2_UNK      5 /* TODO: What is this flag? 20mA loop current? */
216 #define  POS_ICON_STS2_REL      4
217 #define  POS_ICON_STS2_DBM      3
218 #define  POS_ICON_STS2_MINMAX   0 /* TODO: How to interpret the 3-bit field? */
219 #define  LEN_ICON_STS2_MINMAX   3
220         OFF_ICON_STS_3,
221 #define  POS_ICON_STS3_RSV_7    7
222 #define  POS_ICON_STS3_TEST     6
223 #define  POS_ICON_STS3_MEM      4 /* TODO: How to interpret the 2-bit field? */
224 #define  LEN_ICON_STS3_MEM      2
225 #define  POS_ICON_STS3_AHOLD    2
226 #define  LEN_ICON_STS3_AHOLD    2
227 #define  POS_ICON_STS3_AC       1
228 #define  POS_ICON_STS3_DC       0
229         OFF_CHECKSUM,
230         /* This is not an offset, but the packet's "byte count". */
231         PACKET_LAST_OFF,
232 };
233
234 STATIC_ASSERT(PACKET_LAST_OFF == EEV121GW_PACKET_SIZE,
235         "byte offsets vs packet length mismatch");
236
237 enum mode_codes {
238         /* Modes for 'main' and 'sub' displays. */
239         MODE_LOW_Z = 0,
240         MODE_DC_V = 1,
241         MODE_AC_V = 2,
242         MODE_DC_MV = 3,
243         MODE_AC_MV = 4,
244         MODE_TEMP = 5,
245         MODE_FREQ = 6,
246         MODE_PERIOD = 7,
247         MODE_DUTY = 8,
248         MODE_RES = 9,
249         MODE_CONT = 10,
250         MODE_DIODE = 11,
251         MODE_CAP = 12,
252         MODE_AC_UVA = 13,
253         MODE_AC_MVA = 14,
254         MODE_AC_VA = 15,
255         MODE_AC_UA = 16,
256         MODE_DC_UA = 17,
257         MODE_AC_MA = 18,
258         MODE_DC_MA = 19,
259         MODE_AC_A = 20,
260         MODE_DC_A = 21,
261         MODE_DC_UVA = 22,
262         MODE_DC_MVA = 23,
263         MODE_DC_VA = 24,
264         /* More modes for 'sub' display. */
265         MODE_SUB_TEMPC = 100,
266         MODE_SUB_TEMPF = 105,
267         MODE_SUB_BATT = 110,
268         MODE_SUB_APO_ON = 120,
269         MODE_SUB_APO_OFF = 125,
270         MODE_SUB_YEAR = 130,
271         MODE_SUB_DATE = 135,
272         MODE_SUB_TIME = 140,
273         MODE_SUB_B_VOLT = 150,
274         MODE_SUB_LCD = 160,
275         MODE_SUB_CONT_PARM_0 = 170,
276         MODE_SUB_CONT_PARM_1 = 171,
277         MODE_SUB_CONT_PARM_2 = 172,
278         MODE_SUB_CONT_PARM_3 = 173,
279         MODE_SUB_DBM = 180,
280         MODE_SUB_IVAL = 190,
281 };
282
283 enum range_codes {
284         RANGE_0,
285         RANGE_1,
286         RANGE_2,
287         RANGE_3,
288         RANGE_4,
289         RANGE_5,
290         RANGE_6,
291         RANGE_MAX,
292 };
293
294 enum bar_range_codes {
295         BAR_RANGE_5,
296         BAR_RANGE_50,
297         BAR_RANGE_500,
298         BAR_RANGE_1000,
299 };
300 #define BAR_VALUE_MAX 25
301
302 enum acdc_codes {
303         ACDC_NONE,
304         ACDC_DC,
305         ACDC_AC,
306         ACDC_ACDC,
307 };
308
309 SR_PRIV const char *eev121gw_channel_formats[EEV121GW_DISPLAY_COUNT] = {
310         /*
311          * TODO:
312          * The "main", "sub", "bar" names were taken from the packet
313          * description. Will users prefer "primary", "secondary", and
314          * "bargraph" names? Or even-length "pri", "sec", "bar" instead?
315          */
316         "main", "sub", "bar",
317 };
318
319 /*
320  * See page 69 in the 2018-09-24 manual for a table of modes and their
321  * respective ranges ("Calibration Reference Table"). This is the input
322  * to get the number of significant digits, and the decimal's position.
323  */
324 struct mode_range_item {
325         const char *desc; /* Description, for diagnostics. */
326         int digits; /* Number of significant digits, see @ref sr_analog_encoding. */
327         int factor; /* Factor to convert the uint to a float. */
328 };
329
330 struct mode_range_items {
331         size_t range_count;
332         const struct mode_range_item ranges[RANGE_MAX];
333 };
334
335 static const struct mode_range_items mode_ranges_lowz = {
336         .range_count = 1,
337         .ranges = {
338                 { .desc =  "600.0V", .digits = 1, .factor = 1, },
339         },
340 };
341
342 static const struct mode_range_items mode_ranges_volts = {
343         .range_count = 4,
344         .ranges = {
345                 { .desc = "5.0000V", .digits = 4, .factor = 4, },
346                 { .desc = "50.000V", .digits = 3, .factor = 3, },
347                 { .desc = "500.00V", .digits = 2, .factor = 2, },
348                 { .desc =  "600.0V", .digits = 1, .factor = 1, },
349         },
350 };
351
352 static const struct mode_range_items mode_ranges_millivolts = {
353         .range_count = 2,
354         .ranges = {
355                 { .desc = "50.000mV", .digits = 6, .factor = 6, },
356                 { .desc = "500.00mV", .digits = 5, .factor = 5, },
357         },
358 };
359
360 static const struct mode_range_items mode_ranges_temp = {
361         .range_count = 1,
362         .ranges = {
363                 { .desc = "-200.0C ~ 1350.0C", .digits = 1, .factor = 1, },
364         },
365 };
366
367 static const struct mode_range_items mode_ranges_freq = {
368         .range_count = 5,
369         .ranges = {
370                 { .desc = "99.999Hz", .digits = 3, .factor = 3, },
371                 { .desc = "999.99Hz", .digits = 2, .factor = 2, },
372                 { .desc = "9.9999kHz", .digits = 1, .factor = 1, },
373                 { .desc = "99.999kHz", .digits = 0, .factor = 0, },
374                 { .desc = "999.99kHz", .digits = -1, .factor = -1, },
375         },
376 };
377
378 static const struct mode_range_items mode_ranges_period = {
379         .range_count = 3,
380         .ranges = {
381                 { .desc = "9.9999ms", .digits = 7, .factor = 7, },
382                 { .desc = "99.999ms", .digits = 6, .factor = 6, },
383                 { .desc = "999.99ms", .digits = 5, .factor = 5, },
384         },
385 };
386
387 static const struct mode_range_items mode_ranges_duty = {
388         .range_count = 1,
389         .ranges = {
390                 { .desc = "99.9%", .digits = 1, .factor = 1, },
391         },
392 };
393
394 static const struct mode_range_items mode_ranges_res = {
395         .range_count = 7,
396         .ranges = {
397                 { .desc = "50.000R", .digits = 3, .factor = 3, },
398                 { .desc = "500.00R", .digits = 2, .factor = 2, },
399                 { .desc = "5.0000k", .digits = 1, .factor = 1, },
400                 { .desc = "50.000k", .digits = 0, .factor = 0, },
401                 { .desc = "500.00k", .digits = -1, .factor = -1, },
402                 { .desc = "5.0000M", .digits = -2, .factor = -2, },
403                 { .desc = "50.000M", .digits = -3, .factor = -3, },
404         },
405 };
406
407 static const struct mode_range_items mode_ranges_cont = {
408         .range_count = 1,
409         .ranges = {
410                 { .desc = "500.00R", .digits = 2, .factor = 2, },
411         },
412 };
413
414 static const struct mode_range_items mode_ranges_diode = {
415         .range_count = 2,
416         .ranges = {
417                 { .desc = "3.0000V", .digits = 4, .factor = 4, },
418                 { .desc = "15.000V", .digits = 3, .factor = 3, },
419         },
420 };
421
422 static const struct mode_range_items mode_ranges_cap = {
423         .range_count = 6,
424         .ranges = {
425                 { .desc =  "10.00n", .digits = 11, .factor = 11, },
426                 { .desc =  "100.0n", .digits = 10, .factor = 10, },
427                 { .desc =  "1.000u", .digits = 9, .factor = 9, },
428                 { .desc =  "10.00u", .digits = 8, .factor = 8, },
429                 { .desc =  "100.0u", .digits = 7, .factor = 7, },
430                 { .desc =  "10.00m", .digits = 5, .factor = 5, },
431         },
432 };
433
434 static const struct mode_range_items mode_ranges_pow_va = {
435         .range_count = 4,
436         .ranges = {
437                 { .desc = "2500.0mVA", .digits = 4, .factor = 4, },
438                 { .desc = "25000.mVA", .digits = 3, .factor = 3, },
439                 { .desc = "25.000VA", .digits = 3, .factor = 3, },
440                 { .desc = "500.00VA", .digits = 2, .factor = 2, },
441         },
442 };
443
444 static const struct mode_range_items mode_ranges_pow_mva = {
445         .range_count = 4,
446         .ranges = {
447                 { .desc = "25.000mVA", .digits = 6, .factor = 6, },
448                 { .desc = "250.00mVA", .digits = 5, .factor = 5, },
449                 { .desc = "250.00mVA", .digits = 5, .factor = 5, },
450                 { .desc = "2500.0mVA", .digits = 4, .factor = 4, },
451         },
452 };
453
454 static const struct mode_range_items mode_ranges_pow_uva = {
455         .range_count = 4,
456         .ranges = {
457                 { .desc = "250.00uVA", .digits = 8, .factor = 8, },
458                 { .desc = "2500.0uVA", .digits = 7, .factor = 7, },
459                 { .desc = "2500.0uVA", .digits = 7, .factor = 7, },
460                 { .desc = "25000.uVA", .digits = 6, .factor = 6, },
461         },
462 };
463
464 static const struct mode_range_items mode_ranges_curr_a = {
465         .range_count = 3,
466         .ranges = {
467                 { .desc = "500.00mA", .digits = 5, .factor = 5, },
468                 { .desc = "5.0000A", .digits = 4, .factor = 4, },
469                 { .desc = "10.000A", .digits = 3, .factor = 3, },
470         },
471 };
472
473 static const struct mode_range_items mode_ranges_curr_ma = {
474         .range_count = 2,
475         .ranges = {
476                 { .desc = "5.0000mA", .digits = 7, .factor = 7, },
477                 { .desc = "50.000mA", .digits = 6, .factor = 6, },
478         },
479 };
480
481 static const struct mode_range_items mode_ranges_curr_ua = {
482         .range_count = 2,
483         .ranges = {
484                 { .desc = "50.000uA", .digits = 9, .factor = 9, },
485                 { .desc = "500.00uA", .digits = 8, .factor = 8, },
486         },
487 };
488
489 static const struct mode_range_items *mode_ranges_main[] = {
490         [MODE_LOW_Z] = &mode_ranges_lowz,
491         [MODE_DC_V] = &mode_ranges_volts,
492         [MODE_AC_V] = &mode_ranges_volts,
493         [MODE_DC_MV] = &mode_ranges_millivolts,
494         [MODE_AC_MV] = &mode_ranges_millivolts,
495         [MODE_TEMP] = &mode_ranges_temp,
496         [MODE_FREQ] = &mode_ranges_freq,
497         [MODE_PERIOD] = &mode_ranges_period,
498         [MODE_DUTY] = &mode_ranges_duty,
499         [MODE_RES] = &mode_ranges_res,
500         [MODE_CONT] = &mode_ranges_cont,
501         [MODE_DIODE] = &mode_ranges_diode,
502         [MODE_CAP] = &mode_ranges_cap,
503         [MODE_DC_VA] = &mode_ranges_pow_va,
504         [MODE_AC_VA] = &mode_ranges_pow_va,
505         [MODE_DC_MVA] = &mode_ranges_pow_mva,
506         [MODE_AC_MVA] = &mode_ranges_pow_mva,
507         [MODE_DC_UVA] = &mode_ranges_pow_uva,
508         [MODE_AC_UVA] = &mode_ranges_pow_uva,
509         [MODE_DC_A] = &mode_ranges_curr_a,
510         [MODE_AC_A] = &mode_ranges_curr_a,
511         [MODE_DC_MA] = &mode_ranges_curr_ma,
512         [MODE_AC_MA] = &mode_ranges_curr_ma,
513         [MODE_DC_UA] = &mode_ranges_curr_ua,
514         [MODE_AC_UA] = &mode_ranges_curr_ua,
515 };
516
517 /*
518  * The secondary display encodes SI units / scaling differently from the
519  * main display, and fewer ranges are available. So we share logic between
520  * displays for scaling, but have to keep separate tables for the displays.
521  */
522
523 static const struct mode_range_items mode_ranges_temp_sub = {
524         .range_count = 2,
525         .ranges = {
526                 [1] = { .desc = "sub 100.0C", .digits = 1, .factor = 1, },
527         },
528 };
529
530 static const struct mode_range_items mode_ranges_freq_sub = {
531         .range_count = 4,
532         .ranges = {
533                 [1] = { .desc = "999.9Hz", .digits = 1, .factor = 1, },
534                 [2] = { .desc = "99.99Hz", .digits = 2, .factor = 2, },
535                 [3] = { .desc = "9.999kHz", .digits = 3, .factor = 3, },
536         },
537 };
538
539 static const struct mode_range_items mode_ranges_batt_sub = {
540         .range_count = 2,
541         .ranges = {
542                 [1] = { .desc = "sub 10.0V", .digits = 1, .factor = 1, },
543         },
544 };
545
546 static const struct mode_range_items mode_ranges_gain_sub = {
547         .range_count = 4,
548         .ranges = {
549                 [1] = { .desc = "dbm 5000.0dBm", .digits = 1, .factor = 1, },
550                 [2] = { .desc = "dbm 500.00dBm", .digits = 2, .factor = 2, },
551                 [3] = { .desc = "dbm 50.000dBm", .digits = 3, .factor = 3, },
552         },
553 };
554
555 static const struct mode_range_items mode_ranges_diode_sub = {
556         .range_count = 1,
557         .ranges = {
558                 [0] = { .desc = "diode 15.0V", .digits = 0, .factor = 0, },
559         },
560 };
561
562 /* TODO: Complete the list of ranges. Only tested with low voltages so far. */
563 static const struct mode_range_items mode_ranges_volts_sub = {
564         .range_count = 5,
565         .ranges = {
566                 [4] = { .desc = "5.0000V", .digits = 4, .factor = 4, },
567         },
568 };
569
570 /* TODO: Complete the list of ranges. Only tested with low voltages so far. */
571 static const struct mode_range_items mode_ranges_mamps_sub = {
572         .range_count = 3,
573         .ranges = {
574                 [2] = { .desc = "500.00mA", .digits = 5, .factor = 5, },
575         },
576 };
577
578 static const struct mode_range_items *mode_ranges_sub[] = {
579         [MODE_DC_V] = &mode_ranges_volts_sub,
580         [MODE_AC_V] = &mode_ranges_volts_sub,
581         [MODE_DC_A] = &mode_ranges_mamps_sub,
582         [MODE_AC_A] = &mode_ranges_mamps_sub,
583         [MODE_FREQ] = &mode_ranges_freq_sub,
584         [MODE_DIODE] = &mode_ranges_diode_sub,
585         [MODE_SUB_TEMPC] = &mode_ranges_temp_sub,
586         [MODE_SUB_TEMPF] = &mode_ranges_temp_sub,
587         [MODE_SUB_BATT] = &mode_ranges_batt_sub,
588         [MODE_SUB_DBM] = &mode_ranges_gain_sub,
589 };
590
591 static const struct mode_range_item *mode_range_get_scale(
592         enum eev121gw_display display,
593         enum mode_codes mode, enum range_codes range)
594 {
595         const struct mode_range_items *items;
596         const struct mode_range_item *item;
597
598         if (display == EEV121GW_DISPLAY_MAIN) {
599                 if (mode >= ARRAY_SIZE(mode_ranges_main))
600                         return NULL;
601                 items = mode_ranges_main[mode];
602                 if (!items || !items->range_count)
603                         return NULL;
604                 if (range >= items->range_count)
605                         return NULL;
606                 item = &items->ranges[range];
607                 return item;
608         }
609         if (display == EEV121GW_DISPLAY_SUB) {
610                 if (mode >= ARRAY_SIZE(mode_ranges_sub))
611                         return NULL;
612                 items = mode_ranges_sub[mode];
613                 if (!items || !items->range_count)
614                         return NULL;
615                 if (range >= items->range_count)
616                         return NULL;
617                 item = &items->ranges[range];
618                 if (!item->desc || !*item->desc)
619                         return NULL;
620                 return item;
621         }
622
623         return NULL;
624 }
625
626 SR_PRIV gboolean sr_eev121gw_packet_valid(const uint8_t *buf)
627 {
628         uint8_t csum;
629         size_t idx;
630
631         /* Leading byte, literal / fixed value. */
632         if (buf[OFF_START_CMD] != VAL_START_CMD)
633                 return FALSE;
634
635         /* Check some always-zero bits in reserved locations. */
636         if (FIELD_NB(buf[OFF_MAIN_MODE], MAIN_MODE_RSV_5))
637                 return FALSE;
638         if (FIELD_NB(buf[OFF_SUB_RANGE], SUB_RANGE_RSV_3))
639                 return FALSE;
640         if (FIELD_NL(buf[OFF_BAR_STATUS], BAR_STATUS_RSV_5))
641                 return FALSE;
642         if (FIELD_NL(buf[OFF_BAR_VALUE], BAR_VALUE_RSV_6))
643                 return FALSE;
644         /* See TODO for bit 5 of "bar value" not always being 0. */
645         if (0 && FIELD_NB(buf[OFF_BAR_VALUE], BAR_VALUE_RSV_5))
646                 return FALSE;
647         if (FIELD_NB(buf[OFF_ICON_STS_3], ICON_STS3_RSV_7))
648                 return FALSE;
649
650         /* Checksum, XOR over all previous bytes. */
651         csum = 0x00;
652         for (idx = OFF_START_CMD; idx < OFF_CHECKSUM; idx++)
653                 csum ^= buf[idx];
654         if (csum != buf[OFF_CHECKSUM]) {
655                 /* Non-critical condition, almost expected to see invalid data. */
656                 sr_spew("Packet csum: want %02x, got %02x.", csum, buf[OFF_CHECKSUM]);
657                 return FALSE;
658         }
659
660         sr_spew("Packet valid.");
661
662         return TRUE;
663 }
664
665 /**
666  * Parse a protocol packet.
667  *
668  * @param[in] buf Buffer containing the protocol packet. Must not be NULL.
669  * @param[out] floatval Pointer to a float variable. That variable will be
670  *             modified in-place depending on the protocol packet.
671  *             Must not be NULL.
672  * @param[out] analog Pointer to a struct sr_datafeed_analog. The struct will
673  *             be filled with data according to the protocol packet.
674  *             Must not be NULL.
675  * @param[out] info Pointer to a struct eevblog_121gw_info. The struct will be
676  *             filled with data according to the protocol packet.
677  *             Must not be NULL.
678  *
679  * @return SR_OK upon success, SR_ERR upon failure. Upon errors, the
680  *         'analog' variable contents are undefined and should not be used.
681  */
682 SR_PRIV int sr_eev121gw_parse(const uint8_t *buf, float *floatval,
683                 struct sr_datafeed_analog *analog, void *info)
684 {
685         struct eev121gw_info *info_local;
686         enum eev121gw_display display;
687         const char *channel_name;
688         uint32_t raw_serial;
689         uint8_t raw_main_mode, raw_main_range;
690         uint16_t raw_main_value;
691         uint8_t raw_sub_mode, raw_sub_range;
692         uint16_t raw_sub_value;
693         uint8_t raw_bar_status, raw_bar_value;
694         uint8_t raw_icon_stat_1, raw_icon_stat_2, raw_icon_stat_3;
695         uint32_t uint_value;
696         enum mode_codes main_mode;
697         enum range_codes main_range;
698         enum mode_codes sub_mode;
699         enum range_codes sub_range;
700         const struct mode_range_item *scale;
701         gboolean is_dc, is_sign, use_sign;
702         gboolean is_k;
703         unsigned int cont_code;
704
705         info_local = info;
706         display = info_local->ch_idx;
707         channel_name = eev121gw_channel_formats[display];
708         memset(info_local, 0, sizeof(*info_local));
709         *floatval = 0.0f;
710
711         /*
712          * Get the packet's bytes into native C language typed variables.
713          * This keeps byte position references out of logic/calculations.
714          * The start command and CRC were verified before we get here.
715          */
716         raw_serial = RB32(&buf[OFF_SERIAL_3]);
717         raw_main_mode = R8(&buf[OFF_MAIN_MODE]);
718         raw_main_range = R8(&buf[OFF_MAIN_RANGE]);
719         raw_main_value = RB16(&buf[OFF_MAIN_VAL_H]);
720         raw_sub_mode = R8(&buf[OFF_SUB_MODE]);
721         raw_sub_range = R8(&buf[OFF_SUB_RANGE]);
722         raw_sub_value = RB16(&buf[OFF_SUB_VAL_H]);
723         raw_bar_status = R8(&buf[OFF_BAR_STATUS]);
724         raw_bar_value = R8(&buf[OFF_BAR_VALUE]);
725         raw_icon_stat_1 = R8(&buf[OFF_ICON_STS_1]);
726         raw_icon_stat_2 = R8(&buf[OFF_ICON_STS_2]);
727         raw_icon_stat_3 = R8(&buf[OFF_ICON_STS_3]);
728
729         /*
730          * Packets contain a YEAR-MONTH date spec. It's uncertain how
731          * this data relates to the device's production or the firmware
732          * version. It certainly is not the current date either. Only
733          * optionally log this information, it's consistent across all
734          * packets (won't change within a session), and will be noisy if
735          * always enabled.
736          *
737          * Packets also contain a user adjustable device identification
738          * number (see the SETUP options). This is motivated by support
739          * for multiple devices, but won't change here within a session.
740          * The user chose to communicate to one specific device when the
741          * session started, by means of the conn= spec.
742          *
743          * It was suggested that this 'serial' field might be used as an
744          * additional means to check for a packet's validity (or absence
745          * of communication errors). This remains as an option for future
746          * improvement.
747          */
748         if (0) {
749                 unsigned int ser_year, ser_mon, ser_nr;
750
751                 ser_year = FIELD_NL(raw_serial, SERIAL_YEAR);
752                 ser_mon = FIELD_NL(raw_serial, SERIAL_MONTH);
753                 ser_nr = FIELD_NL(raw_serial, SERIAL_NUMBER);
754                 sr_spew("Packet: Y-M %x-%x, nr %x.", ser_year, ser_mon, ser_nr);
755         }
756
757         switch (display) {
758
759         case EEV121GW_DISPLAY_MAIN:
760                 /*
761                  * Get those fields which correspond to the main display.
762                  * The value's mantissa has 18 bits. The sign is separate
763                  * (and is not universally applicable, mode needs to get
764                  * inspected). The range's scaling and precision also
765                  * depend on the mode.
766                  */
767                 main_mode = FIELD_NL(raw_main_mode, MAIN_MODE_MODE);
768                 main_range = FIELD_NL(raw_main_range, MAIN_RANGE_RANGE);
769                 scale = mode_range_get_scale(EEV121GW_DISPLAY_MAIN,
770                         main_mode, main_range);
771                 if (!scale)
772                         return SR_ERR_NA;
773                 info_local->factor = scale->factor;
774                 info_local->digits = scale->digits;
775
776                 uint_value = raw_main_value;
777                 uint_value |= FIELD_NL(raw_main_mode, MAIN_MODE_VAL_U) << 16;
778                 info_local->uint_value = uint_value;
779                 info_local->is_ofl = FIELD_NB(raw_main_range, MAIN_RANGE_OFL);
780
781                 switch (main_mode) {
782                 case MODE_LOW_Z:
783                         is_dc = FALSE;
784                         if (FIELD_NB(raw_icon_stat_3, ICON_STS3_DC))
785                                 is_dc = TRUE;
786                         if (FIELD_NB(raw_icon_stat_3, ICON_STS3_AC))
787                                 is_dc = FALSE;
788                         use_sign = is_dc;
789                         break;
790                 case MODE_DC_V:
791                 case MODE_DC_MV:
792                 case MODE_TEMP:
793                 case MODE_DC_UVA:
794                 case MODE_DC_MVA:
795                 case MODE_DC_VA:
796                 case MODE_DC_UA:
797                 case MODE_DC_MA:
798                 case MODE_DC_A:
799                         use_sign = TRUE;
800                         break;
801                 default:
802                         use_sign = FALSE;
803                         break;
804                 }
805                 if (use_sign) {
806                         is_sign = FIELD_NB(raw_main_range, MAIN_RANGE_SIGN);
807                         info_local->is_neg = is_sign;
808                 }
809
810                 switch (main_mode) {
811                 case MODE_LOW_Z:
812                         info_local->is_voltage = TRUE;
813                         /* TODO: Need to determine AC/DC here? */
814                         info_local->is_volt = TRUE;
815                         info_local->is_low_pass = TRUE;
816                         break;
817                 case MODE_DC_V:
818                         info_local->is_voltage = TRUE;
819                         info_local->is_dc = TRUE;
820                         info_local->is_volt = TRUE;
821                         break;
822                 case MODE_AC_V:
823                         info_local->is_voltage = TRUE;
824                         info_local->is_volt = TRUE;
825                         info_local->is_ac = TRUE;
826                         break;
827                 case MODE_DC_MV:
828                         info_local->is_voltage = TRUE;
829                         info_local->is_dc = TRUE;
830                         info_local->is_volt = TRUE;
831                         break;
832                 case MODE_AC_MV:
833                         info_local->is_voltage = TRUE;
834                         info_local->is_volt = TRUE;
835                         info_local->is_ac = TRUE;
836                         break;
837                 case MODE_TEMP:
838                         info_local->is_temperature = TRUE;
839                         if (FIELD_NB(raw_main_range, MAIN_RANGE_DEGC))
840                                 info_local->is_celsius = TRUE;
841                         if (FIELD_NB(raw_main_range, MAIN_RANGE_DEGF))
842                                 info_local->is_fahrenheit = TRUE;
843                         break;
844                 case MODE_FREQ:
845                         info_local->is_frequency = TRUE;
846                         info_local->is_hertz = TRUE;
847                         break;
848                 case MODE_PERIOD:
849                         info_local->is_period = TRUE;
850                         info_local->is_seconds = TRUE;
851                         break;
852                 case MODE_DUTY:
853                         info_local->is_duty_cycle = TRUE;
854                         info_local->is_percent = TRUE;
855                         break;
856                 case MODE_RES:
857                         info_local->is_resistance = TRUE;
858                         info_local->is_ohm = TRUE;
859                         break;
860                 case MODE_CONT:
861                         info_local->is_continuity = TRUE;
862                         info_local->is_ohm = TRUE;
863                         /*
864                          * In continuity mode the packet provides the
865                          * resistance in ohms (500R range), but seems to
866                          * _not_ carry the "boolean" open/closed state
867                          * which controls the beeper. Users can select
868                          * whether to trigger at 30R or 300R, and whether
869                          * to trigger on values below (continuity) or
870                          * above (cable break) the limit, but we cannot
871                          * tell what the currently used setting is. So
872                          * we neither get the beeper's state, nor can we
873                          * derive it from other information.
874                          */
875                         break;
876                 case MODE_DIODE:
877                         info_local->is_diode = TRUE;
878                         info_local->is_dc = TRUE;
879                         info_local->is_volt = TRUE;
880                         break;
881                 case MODE_CAP:
882                         info_local->is_capacitance = TRUE;
883                         info_local->is_farad = TRUE;
884                         break;
885                 case MODE_AC_UVA:
886                         info_local->is_power = TRUE;
887                         info_local->is_ac = TRUE;
888                         info_local->is_volt_ampere = TRUE;
889                         break;
890                 case MODE_AC_MVA:
891                         info_local->is_power = TRUE;
892                         info_local->is_ac = TRUE;
893                         info_local->is_volt_ampere = TRUE;
894                         break;
895                 case MODE_AC_VA:
896                         info_local->is_power = TRUE;
897                         info_local->is_ac = TRUE;
898                         info_local->is_volt_ampere = TRUE;
899                         break;
900                 case MODE_AC_UA:
901                         info_local->is_current = TRUE;
902                         info_local->is_ac = TRUE;
903                         info_local->is_ampere = TRUE;
904                         break;
905                 case MODE_DC_UA:
906                         info_local->is_current = TRUE;
907                         info_local->is_dc = TRUE;
908                         info_local->is_ampere = TRUE;
909                         break;
910                 case MODE_AC_MA:
911                         info_local->is_current = TRUE;
912                         info_local->is_ac = TRUE;
913                         info_local->is_ampere = TRUE;
914                         break;
915                 case MODE_DC_MA:
916                         info_local->is_current = TRUE;
917                         info_local->is_dc = TRUE;
918                         info_local->is_ampere = TRUE;
919                         break;
920                 case MODE_AC_A:
921                         info_local->is_current = TRUE;
922                         info_local->is_ac = TRUE;
923                         info_local->is_ampere = TRUE;
924                         break;
925                 case MODE_DC_A:
926                         info_local->is_current = TRUE;
927                         info_local->is_dc = TRUE;
928                         info_local->is_ampere = TRUE;
929                         break;
930                 case MODE_DC_UVA:
931                         info_local->is_power = TRUE;
932                         info_local->is_dc = TRUE;
933                         info_local->is_volt_ampere = TRUE;
934                         break;
935                 case MODE_DC_MVA:
936                         info_local->is_power = TRUE;
937                         info_local->is_dc = TRUE;
938                         info_local->is_volt_ampere = TRUE;
939                         break;
940                 case MODE_DC_VA:
941                         info_local->is_power = TRUE;
942                         info_local->is_dc = TRUE;
943                         info_local->is_volt_ampere = TRUE;
944                         break;
945                 /* Modes 100-199 only apply to the secondary display. */
946                 default:
947                         return SR_ERR_NA;
948                 }
949
950                 /*
951                  * Inspect the "icons" section, since it is associated
952                  * with the primary display and global device state.
953                  */
954                 if (FIELD_NB(raw_icon_stat_1, ICON_STS1_1KHZ))
955                         info_local->is_low_pass = TRUE;
956                 if (FIELD_NB(raw_icon_stat_1, ICON_STS1_1MSPK))
957                         info_local->is_1ms_peak = TRUE;
958                 switch (FIELD_NL(raw_icon_stat_1, ICON_STS1_DCAC)) {
959                 case ACDC_ACDC:
960                         info_local->is_ac = TRUE;
961                         info_local->is_dc = TRUE;
962                         break;
963                 case ACDC_AC:
964                         info_local->is_ac = TRUE;
965                         break;
966                 case ACDC_DC:
967                         info_local->is_dc = TRUE;
968                         break;
969                 case ACDC_NONE:
970                         /* EMPTY */
971                         break;
972                 }
973                 if (FIELD_NB(raw_icon_stat_1, ICON_STS1_AUTO))
974                         info_local->is_auto_range = TRUE;
975                 if (FIELD_NB(raw_icon_stat_1, ICON_STS1_APO))
976                         info_local->is_auto_poweroff = TRUE;
977                 if (FIELD_NB(raw_icon_stat_1, ICON_STS1_BAT))
978                         info_local->is_low_batt = TRUE;
979                 if (FIELD_NB(raw_icon_stat_2, ICON_STS2_BT))
980                         info_local->is_bt = TRUE;
981                 /* TODO: Is this the "20mA loop current" flag? */
982                 if (FIELD_NB(raw_icon_stat_2, ICON_STS2_UNK))
983                         info_local->is_loop_current = TRUE;
984                 if (FIELD_NB(raw_icon_stat_2, ICON_STS2_REL))
985                         info_local->is_rel = TRUE;
986                 /* dBm only applies to secondary display, not main. */
987                 switch (FIELD_NL(raw_icon_stat_2, ICON_STS2_MINMAX)) {
988                 /* TODO: Do inspect the min/max/avg flags. */
989                 default:
990                         /* EMPTY */
991                         break;
992                 }
993                 if (FIELD_NB(raw_icon_stat_3, ICON_STS3_TEST))
994                         info_local->is_test = TRUE;
995                 /* TODO: How to interpret the 2-bit MEM field? */
996                 if (FIELD_NL(raw_icon_stat_3, ICON_STS3_MEM))
997                         info_local->is_mem = TRUE;
998                 if (FIELD_NL(raw_icon_stat_3, ICON_STS3_AHOLD))
999                         info_local->is_hold = TRUE;
1000                 /* TODO: Are these for the secondary display? See status-2 ACDC. */
1001                 if (FIELD_NB(raw_icon_stat_3, ICON_STS3_AC))
1002                         info_local->is_ac = TRUE;
1003                 if (FIELD_NB(raw_icon_stat_3, ICON_STS3_DC))
1004                         info_local->is_dc = TRUE;
1005
1006                 sr_spew("Disp '%s', value: %lu (ov %d, neg %d), mode %d, range %d.",
1007                         channel_name,
1008                         (unsigned long)info_local->uint_value,
1009                         info_local->is_ofl, info_local->is_neg,
1010                         (int)main_mode, (int)main_range);
1011                 /* Advance to the number and units conversion below. */
1012                 break;
1013
1014         case EEV121GW_DISPLAY_SUB:
1015                 /*
1016                  * Get those fields which correspond to the secondary
1017                  * display. The value's mantissa has 16 bits. The sign
1018                  * is separate is only applies to some of the modes.
1019                  * Scaling and precision also depend on the mode. The
1020                  * interpretation of the secondary display is different
1021                  * from the main display: The 'range' is not an index
1022                  * into ranges, instead it's the decimal's position.
1023                  * Yet more scaling depends on the mode, to complicate
1024                  * matters. The secondary display uses modes 100-199,
1025                  * and some of the 0-24 modes as well.
1026                  */
1027                 sub_mode = FIELD_NL(raw_sub_mode, SUB_MODE_MODE);
1028                 sub_range = FIELD_NL(raw_sub_range, SUB_RANGE_POINT);
1029                 scale = mode_range_get_scale(EEV121GW_DISPLAY_SUB,
1030                         sub_mode, sub_range);
1031                 if (!scale)
1032                         return SR_ERR_NA;
1033                 info_local->factor = scale->factor;
1034                 info_local->digits = scale->digits;
1035
1036                 info_local->uint_value = raw_sub_value;
1037                 info_local->is_ofl = FIELD_NB(raw_sub_range, SUB_RANGE_OFL);
1038
1039                 switch (sub_mode) {
1040                 case MODE_DC_V:
1041                 case MODE_AC_V:
1042                 case MODE_DC_A:
1043                 case MODE_AC_A:
1044                 case MODE_SUB_TEMPC:
1045                 case MODE_SUB_TEMPF:
1046                 case MODE_SUB_B_VOLT:
1047                 case MODE_SUB_DBM:
1048                         use_sign = TRUE;
1049                         break;
1050                 default:
1051                         use_sign = FALSE;
1052                         break;
1053                 }
1054                 if (use_sign) {
1055                         is_sign = FIELD_NB(raw_sub_range, SUB_RANGE_SIGN);
1056                         info_local->is_neg = is_sign;
1057                 }
1058                 is_k = FIELD_NB(raw_sub_range, SUB_RANGE_K);
1059
1060                 /*
1061                  * TODO: Re-check the power mode display as more data becomes
1062                  * available.
1063                  *
1064                  * The interpretation of the secondary display in power (VA)
1065                  * modes is uncertain. The mode suggests A or uA units but the
1066                  * value is supposed to be mA without a reliable condition
1067                  * for us to check...
1068                  *
1069                  * f2  17 84 21 21  18 02 00 00  01 04 00 0b  00 00  0a 40 00  3f
1070                  * f2  17 84 21 21  18 02 00 00  15 03 00 00  00 00  0a 40 00  27
1071                  *                  DC VA        DC V / DC A
1072                  *                  25.000VA     dot 4 / dot 3
1073                  *
1074                  * f2  17 84 21 21  18 00 00 26  01 04 4c 57  00 00  0e 40 00  0f
1075                  * f2  17 84 21 21  18 00 00 26  15 02 00 c7  00 00  0e 40 00  c1
1076                  *                  3.8mVA DC    1.9543V
1077                  *                                 1.98mA (!) DC A + dot 2 -> milli(!) amps?
1078                  *
1079                  * f2  17 84 21 21  17 00 07 85  01 04 4c 5a  00 00  0e 40 00  a9
1080                  * f2  17 84 21 21  17 00 07 85  13 04 26 7b  00 00  0e 40 00  f0
1081                  *                  1.925mVA DC  1.9546V
1082                  *                               0.9852mA
1083                  *
1084                  * f2  17 84 21 21  16 02 11 e0  01 04 26 39  00 02  0e 40 00  d2
1085                  * f2  17 84 21 21  16 02 11 e0  11 04 12 44  00 02  0e 40 00  8b
1086                  *                  457.6uVA DC  0.9785V
1087                  *                               0.4676mA (!) DC uA + dot 4 -> milli(!) amps?
1088                  */
1089
1090                 switch (sub_mode) {
1091                 case MODE_DC_V:
1092                         info_local->is_voltage = TRUE;
1093                         info_local->is_volt = TRUE;
1094                         break;
1095                 case MODE_DC_A:
1096                         info_local->is_current = TRUE;
1097                         info_local->is_ampere = TRUE;
1098                         break;
1099                 case MODE_FREQ:
1100                         info_local->is_frequency = TRUE;
1101                         info_local->is_hertz = TRUE;
1102                         if (is_k) {
1103                                 info_local->factor -= 3;
1104                                 info_local->digits -= 3;
1105                         }
1106                         info_local->is_ofl = FALSE;
1107                         break;
1108                 case MODE_SUB_TEMPC:
1109                         info_local->is_temperature = TRUE;
1110                         info_local->is_celsius = TRUE;
1111                         break;
1112                 case MODE_SUB_TEMPF:
1113                         info_local->is_temperature = TRUE;
1114                         info_local->is_fahrenheit = TRUE;
1115                         break;
1116                 case MODE_SUB_BATT:
1117                         /* TODO: How to communicate it's the *battery* voltage? */
1118                         info_local->is_voltage = TRUE;
1119                         info_local->is_volt = TRUE;
1120                         break;
1121                 case MODE_SUB_DBM:
1122                         info_local->is_gain = TRUE;
1123                         info_local->is_dbm = TRUE;
1124                         break;
1125                 case MODE_SUB_CONT_PARM_0:
1126                 case MODE_SUB_CONT_PARM_1:
1127                 case MODE_SUB_CONT_PARM_2:
1128                 case MODE_SUB_CONT_PARM_3:
1129                         /*
1130                          * These "continuity parameters" are special. The
1131                          * least significant bits represent the options:
1132                          *
1133                          * 0xaa = 170 => down 30
1134                          * 0xab = 171 => up 30
1135                          * 0xac = 172 => down 300
1136                          * 0xad = 173 => up 300
1137                          *
1138                          * bit 0 value 0 -> close (cont)
1139                          * bit 0 value 1 -> open (break)
1140                          * bit 1 value 0 -> 30R limit
1141                          * bit 1 value 1 -> 300R limit
1142                          *
1143                          * This "display value" is only seen during setup
1144                          * but not during regular operation of continuity
1145                          * mode. :( In theory we could somehow pass the
1146                          * 30/300 ohm limit to sigrok, but that'd be of
1147                          * somewhat limited use.
1148                          */
1149                         cont_code = sub_mode - MODE_SUB_CONT_PARM_0;
1150                         info_local->is_resistance = TRUE;
1151                         info_local->is_ohm = TRUE;
1152                         info_local->uint_value = (cont_code & 0x02) ? 300 : 30;
1153                         info_local->is_neg = FALSE;
1154                         info_local->is_ofl = FALSE;
1155                         info_local->factor = 0;
1156                         info_local->digits = 0;
1157                         break;
1158                 case MODE_DIODE:
1159                         /* Displays configured diode test voltage. */
1160                         info_local->is_voltage = TRUE;
1161                         info_local->is_volt = TRUE;
1162                         break;
1163
1164                 /* Reflecting these to users seems pointless, ignore them. */
1165                 case MODE_SUB_APO_ON:
1166                 case MODE_SUB_APO_OFF:
1167                 case MODE_SUB_LCD:
1168                 case MODE_SUB_YEAR:
1169                 case MODE_SUB_DATE:
1170                 case MODE_SUB_TIME:
1171                         return SR_ERR_NA;
1172
1173                 /* Unknown / unsupported sub display mode. */
1174                 default:
1175                         return SR_ERR_NA;
1176                 }
1177
1178                 sr_spew("disp '%s', value: %lu (ov %d, neg %d), mode %d, range %d",
1179                         channel_name,
1180                         (unsigned long)info_local->uint_value,
1181                         info_local->is_ofl, info_local->is_neg,
1182                         (int)sub_mode, (int)sub_range);
1183                 /* Advance to the number and units conversion below. */
1184                 break;
1185
1186         case EEV121GW_DISPLAY_BAR:
1187                 /*
1188                  * Get those fields which correspond to the bargraph.
1189                  * There are 26 segments (ticks 0-25), several ranges
1190                  * apply (up to 5, or up to 10, several decades). The
1191                  * bargraph does not apply to all modes and ranges,
1192                  * hence there is a "use" flag (negative logic, blank
1193                  * signal). Bit 5 was also found to have undocumented
1194                  * values, we refuse to use the bargraph value then.
1195                  */
1196                 if (FIELD_NB(raw_bar_status, BAR_STATUS_USE))
1197                         return SR_ERR_NA;
1198                 if (FIELD_NB(raw_bar_value, BAR_VALUE_RSV_5))
1199                         return SR_ERR_NA;
1200                 uint_value = FIELD_NL(raw_bar_value, BAR_VALUE_VALUE);
1201                 if (uint_value > BAR_VALUE_MAX)
1202                         uint_value = BAR_VALUE_MAX;
1203                 info_local->is_neg = FIELD_NB(raw_bar_status, BAR_STATUS_SIGN);
1204                 switch (FIELD_NL(raw_bar_status, BAR_STATUS_1K_500)) {
1205                 case BAR_RANGE_5:
1206                         /* Full range 5.0, in steps of 0.2 each. */
1207                         uint_value *= 5000 / BAR_VALUE_MAX;
1208                         info_local->factor = 3;
1209                         info_local->digits = 1;
1210                         break;
1211                 case BAR_RANGE_50:
1212                         /* Full range 50, in steps of 2 each. */
1213                         uint_value *= 50 / BAR_VALUE_MAX;
1214                         info_local->factor = 0;
1215                         info_local->digits = 0;
1216                         break;
1217                 case BAR_RANGE_500:
1218                         /* Full range 500, in steps of 20 each. */
1219                         uint_value *= 500 / BAR_VALUE_MAX;
1220                         info_local->factor = 0;
1221                         info_local->digits = -1;
1222                         break;
1223                 case BAR_RANGE_1000:
1224                         /* Full range 1000, in steps of 40 each. */
1225                         uint_value *= 1000 / BAR_VALUE_MAX;
1226                         info_local->factor = 0;
1227                         info_local->digits = -1;
1228                         break;
1229                 default:
1230                         return SR_ERR_NA;
1231                 }
1232                 info_local->uint_value = uint_value;
1233                 info_local->is_unitless = TRUE;
1234                 sr_spew("Disp '%s', value: %u.", channel_name,
1235                         (unsigned int)info_local->uint_value);
1236                 /* Advance to the number and units conversion below. */
1237                 break;
1238
1239         default:
1240                 /* Unknown display, programmer's error, ShouldNotHappen(TM). */
1241                 sr_err("Disp '-?-'.");
1242                 return SR_ERR_ARG;
1243         }
1244
1245         /*
1246          * Convert the unsigned mantissa and its modifiers to a float
1247          * analog value, including scale and quantity. Do the conversion
1248          * first, and optionally override the result with 'inf' later.
1249          * Apply the sign last so that +inf and -inf are supported.
1250          */
1251         *floatval = info_local->uint_value;
1252         if (info_local->factor)
1253                 *floatval *= powf(10, -info_local->factor);
1254         if (info_local->is_ofl)
1255                 *floatval = INFINITY;
1256         if (info_local->is_neg)
1257                 *floatval = -*floatval;
1258
1259         analog->encoding->digits = info_local->digits;
1260         analog->spec->spec_digits = info_local->digits;
1261
1262         /*
1263          * Communicate the measured quantity.
1264          */
1265         /* Determine the quantity itself. */
1266         if (info_local->is_voltage)
1267                 analog->meaning->mq = SR_MQ_VOLTAGE;
1268         if (info_local->is_current)
1269                 analog->meaning->mq = SR_MQ_CURRENT;
1270         if (info_local->is_power)
1271                 analog->meaning->mq = SR_MQ_POWER;
1272         if (info_local->is_gain)
1273                 analog->meaning->mq = SR_MQ_GAIN;
1274         if (info_local->is_resistance)
1275                 analog->meaning->mq = SR_MQ_RESISTANCE;
1276         if (info_local->is_capacitance)
1277                 analog->meaning->mq = SR_MQ_CAPACITANCE;
1278         if (info_local->is_diode)
1279                 analog->meaning->mq = SR_MQ_VOLTAGE;
1280         if (info_local->is_temperature)
1281                 analog->meaning->mq = SR_MQ_TEMPERATURE;
1282         if (info_local->is_continuity)
1283                 analog->meaning->mq = SR_MQ_CONTINUITY;
1284         if (info_local->is_frequency)
1285                 analog->meaning->mq = SR_MQ_FREQUENCY;
1286         if (info_local->is_period)
1287                 analog->meaning->mq = SR_MQ_TIME;
1288         if (info_local->is_duty_cycle)
1289                 analog->meaning->mq = SR_MQ_DUTY_CYCLE;
1290         if (info_local->is_unitless)
1291                 analog->meaning->mq = SR_MQ_COUNT;
1292         /* Add AC / DC / DC+AC flags. */
1293         if (info_local->is_ac)
1294                 analog->meaning->mqflags |= SR_MQFLAG_AC;
1295         if (info_local->is_dc)
1296                 analog->meaning->mqflags |= SR_MQFLAG_DC;
1297         /* Specify units. */
1298         if (info_local->is_ampere)
1299                 analog->meaning->unit = SR_UNIT_AMPERE;
1300         if (info_local->is_volt)
1301                 analog->meaning->unit = SR_UNIT_VOLT;
1302         if (info_local->is_volt_ampere)
1303                 analog->meaning->unit = SR_UNIT_VOLT_AMPERE;
1304         if (info_local->is_dbm)
1305                 analog->meaning->unit = SR_UNIT_DECIBEL_VOLT;
1306         if (info_local->is_ohm)
1307                 analog->meaning->unit = SR_UNIT_OHM;
1308         if (info_local->is_farad)
1309                 analog->meaning->unit = SR_UNIT_FARAD;
1310         if (info_local->is_celsius)
1311                 analog->meaning->unit = SR_UNIT_CELSIUS;
1312         if (info_local->is_fahrenheit)
1313                 analog->meaning->unit = SR_UNIT_FAHRENHEIT;
1314         if (info_local->is_hertz)
1315                 analog->meaning->unit = SR_UNIT_HERTZ;
1316         if (info_local->is_seconds)
1317                 analog->meaning->unit = SR_UNIT_SECOND;
1318         if (info_local->is_percent)
1319                 analog->meaning->unit = SR_UNIT_PERCENTAGE;
1320         if (info_local->is_loop_current)
1321                 analog->meaning->unit = SR_UNIT_PERCENTAGE;
1322         if (info_local->is_unitless)
1323                 analog->meaning->unit = SR_UNIT_UNITLESS;
1324         if (info_local->is_logic)
1325                 analog->meaning->unit = SR_UNIT_UNITLESS;
1326         /* Add other indicator flags. */
1327         if (info_local->is_diode) {
1328                 analog->meaning->mqflags |= SR_MQFLAG_DIODE;
1329                 analog->meaning->mqflags |= SR_MQFLAG_DC;
1330         }
1331         if (info_local->is_min)
1332                 analog->meaning->mqflags |= SR_MQFLAG_MIN;
1333         if (info_local->is_max)
1334                 analog->meaning->mqflags |= SR_MQFLAG_MAX;
1335         if (info_local->is_avg)
1336                 analog->meaning->mqflags |= SR_MQFLAG_AVG;
1337         /* TODO: How to communicate info_local->is_1ms_peak? */
1338         if (info_local->is_rel)
1339                 analog->meaning->mqflags |= SR_MQFLAG_RELATIVE;
1340         if (info_local->is_hold)
1341                 analog->meaning->mqflags |= SR_MQFLAG_HOLD;
1342         /* TODO: How to communicate info_local->is_low_pass? */
1343         if (info_local->is_mem) /* XXX Is REF appropriate here? */
1344                 analog->meaning->mqflags |= SR_MQFLAG_REFERENCE;
1345         if (info_local->is_auto_range)
1346                 analog->meaning->mqflags |= SR_MQFLAG_AUTORANGE;
1347         /* TODO: How to communicate info->is_test? What's its meaning at all? */
1348         /* TODO: How to communicate info->is_auto_poweroff? */
1349         /* TODO: How to communicate info->is_low_batt? */
1350
1351         return SR_OK;
1352 }
1353
1354 /*
1355  * Parse the same packet multiple times, to extract individual analog
1356  * values which correspond to several displays of the device. Make sure
1357  * to keep the channel index in place, even if the parse routine will
1358  * clear the info structure.
1359  */
1360 SR_PRIV int sr_eev121gw_3displays_parse(const uint8_t *buf, float *floatval,
1361                 struct sr_datafeed_analog *analog, void *info)
1362 {
1363         struct eev121gw_info *info_local;
1364         size_t ch_idx;
1365         int rc;
1366
1367         info_local = info;
1368         ch_idx = info_local->ch_idx;
1369         rc = sr_eev121gw_parse(buf, floatval, analog, info);
1370         info_local->ch_idx = ch_idx + 1;
1371
1372         return rc;
1373 }