]> sigrok.org Git - libsigrok.git/blob - hardware/gmc-mh-1x-2x/protocol.c
gmc_mh_1x_2x: Fixed sign and AC/DC for current measurements with Metrahit <= 16.
[libsigrok.git] / hardware / gmc-mh-1x-2x / protocol.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2013 Matthias Heidbrink <m-sigrok@heidbrink.biz>
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 <math.h>
21 #include <string.h>
22 #include "protocol.h"
23
24 /** Set or clear flags in devc->mqflags. */
25 static void setmqf(struct dev_context *devc, uint64_t flags, gboolean set)
26 {
27         if (set)
28                 devc->mqflags |= flags;
29         else
30                 devc->mqflags &= ~flags;
31 }
32
33 /** Decode current type and measured value, Metrahit 12-16. */
34 static void decode_ctmv_16(uint8_t ctmv, struct dev_context *devc)
35 {
36         devc->mq = 0;
37         devc->unit = 0;
38         devc->mqflags = 0;
39
40         switch (ctmv) {
41         case 0x00: /* 0000 - */
42                 break;
43         case 0x01: /* 0001 mV DC */
44                 devc->scale1000 = -1; /* Fall through */
45         case 0x02: /* 0010 V DC */
46         case 0x03: /* 0011 V AC+DC */
47         case 0x04: /* 0100 V AC */
48                 devc->mq = SR_MQ_VOLTAGE;
49                 devc->unit = SR_UNIT_VOLT;
50                 if (ctmv <= 0x03)
51                         devc->mqflags |= SR_MQFLAG_DC;
52                 if (ctmv >= 0x03) {
53                         devc->mqflags |= SR_MQFLAG_AC;
54                         if (devc->model >= METRAHIT_16S)
55                                 devc->mqflags |= SR_MQFLAG_RMS;
56                 }
57                 break;
58         case 0x05: /* 0101 Hz (15S/16S only) */
59         case 0x06: /* 0110 kHz (15S/16S only) */
60                 devc->mq = SR_MQ_FREQUENCY;
61                 devc->unit = SR_UNIT_HERTZ;
62                 if (ctmv == 0x06)
63                         devc->scale1000 = 1;
64                 break;
65         case 0x07: /* 0111 % (15S/16S only) */
66                 devc->mq = SR_MQ_DUTY_CYCLE;
67                 devc->unit = SR_UNIT_PERCENTAGE;
68                 break;
69         case 0x08: /* 1000 Diode */
70                 devc->mq = SR_MQ_VOLTAGE;
71                 devc->unit = SR_UNIT_VOLT;
72                 devc->mqflags |= SR_MQFLAG_DIODE;
73                 break;
74         case 0x09: /* 1001 Ohm, °C */
75         case 0x0a: /* 1010 kOhm */
76         case 0x0b: /* 1011 MOhm */
77                 devc->mq = SR_MQ_RESISTANCE; /* Changed to temp. later if req.*/
78                 devc->unit = SR_UNIT_OHM;
79                 devc->scale1000 = ctmv - 0x09;
80                 break;
81         case 0x0c: /* 1100 nF (15S/16S only) */
82         case 0x0d: /* 1101 µF (15S/16S only) */
83                 devc->mq = SR_MQ_CAPACITANCE;
84                 devc->unit = SR_UNIT_FARAD;
85                 if (ctmv == 0x0c)
86                         devc->scale1000 = -3;
87                 else
88                         devc->scale1000 = -2;
89                 break;
90         case 0x0e: /* mA, µA */
91                 devc->scale1000 = -1; /* Fall through. */
92         case 0x0f: /* A */
93                 devc->mq = SR_MQ_CURRENT;
94                 devc->unit = SR_UNIT_AMPERE;
95                 if (devc->model == METRAHIT_16S)
96                         devc->mqflags |= SR_MQFLAG_RMS;
97                 /* 16I A only with clamp, RMS questionable. */
98                 break;
99         }
100 }
101
102 /**
103  * Decode range/sign/acdc byte special chars (Metrahit 12-16).
104  *
105  * @param[in] rs Range and sign byte.
106  */
107 static void decode_rs_16(uint8_t rs, struct dev_context *devc)
108 {
109         sr_spew("decode_rs_16(%d) scale = %f", rs, devc->scale);
110
111         if (rs & 0x04) /* Sign */
112                 devc->scale *= -1.0;
113
114         if (devc->mq == SR_MQ_CURRENT) {
115                 if (rs & 0x08) /* Current is AC */
116                         devc->mqflags |= SR_MQFLAG_AC;
117                 else
118                         devc->mqflags |= SR_MQFLAG_DC;
119         }
120
121         switch (rs & 0x03) {
122         case 0:
123                 if (devc->mq == SR_MQ_VOLTAGE) /* V */
124                         devc->scale *= 0.1;
125                 else if (devc->mq == SR_MQ_CURRENT) /* 000.0 µA */
126                         devc->scale *= 0.0000001; /* Untested! */
127                 else if (devc->mq == SR_MQ_RESISTANCE) {
128                         if (devc->buflen >= 10) {
129                                 /* °C with 10 byte msg type, otherwise GOhm. */
130                                 devc->mq = SR_MQ_TEMPERATURE;
131                                 devc->unit = SR_UNIT_CELSIUS;
132                                 devc->scale *= 0.01;
133                         } else if (devc->scale1000 == 2) {
134                                 /* 16I Iso 500/1000V 3 GOhm */
135                                 devc->scale *= 0.1;
136                         }
137                 }
138                 break;
139         case 1:
140                 devc->scale *= 0.0001;
141                 break;
142         case 2:
143                 devc->scale *= 0.001;
144                 break;
145         case 3:
146                 devc->scale *= 0.01;
147                 break;
148         }
149 }
150
151 /**
152  * Decode special chars, Metrahit 12-16.
153  *
154  * @param[in] spc Special characters 1 and 2 (s1 | (s2 << 4)).
155  */
156 static void decode_spc_16(uint8_t spc, struct dev_context *devc)
157 {
158         /* xxxx1xxx ON */
159         /* TODO: What does that mean? Power on? The 16I sets this. */
160         /* xxxxx1xx BEEP */
161         /* xxxxxx1x Low battery */
162         /* xxxxxxx1 FUSE */
163         /* 1xxxxxxx MIN */
164         setmqf(devc, SR_MQFLAG_MIN, spc & 0x80);
165
166         /* x1xxxxxx MAN */
167         setmqf(devc, SR_MQFLAG_AUTORANGE, !(spc & 0x40));
168
169         /* xx1xxxxx DATA */
170         setmqf(devc, SR_MQFLAG_HOLD, spc & 0x20);
171
172         /* xxx1xxxx MAX */
173         setmqf(devc, SR_MQFLAG_MAX, spc & 0x10);
174 }
175
176 /** Decode current type and measured value, Metrahit 18. */
177 static void decode_ctmv_18(uint8_t ctmv, struct dev_context *devc)
178 {
179         devc->mq = 0;
180         devc->unit = 0;
181         devc->mqflags = 0;
182
183         switch (ctmv) {
184         case 0x00: /* 0000 - */
185                 break;
186         case 0x01: /* 0001 V AC */
187         case 0x02: /* 0010 V AC+DC */
188         case 0x03: /* 0011 V DC */
189                 devc->mq = SR_MQ_VOLTAGE;
190                 devc->unit = SR_UNIT_VOLT;
191                 if (ctmv <= 0x02)
192                         devc->mqflags |= (SR_MQFLAG_AC | SR_MQFLAG_RMS);
193                 if (ctmv >= 0x02)
194                         devc->mqflags |= SR_MQFLAG_DC;
195                 break;
196         case 0x04: /* 0100 Ohm/Ohm with buzzer */
197                 devc->mq = SR_MQ_RESISTANCE;
198                 devc->unit = SR_UNIT_OHM;
199                 break;
200         case 0x05: /* 0101 Diode/Diode with buzzer */
201                 devc->mq = SR_MQ_VOLTAGE;
202                 devc->unit = SR_UNIT_VOLT;
203                 devc->mqflags |= SR_MQFLAG_DIODE;
204                 break;
205         case 0x06: /* 0110 °C */
206                 devc->mq = SR_MQ_TEMPERATURE;
207                 devc->unit = SR_UNIT_CELSIUS;
208                 break;
209         case 0x07: /* 0111 F */
210                 devc->mq = SR_MQ_CAPACITANCE;
211                 devc->unit = SR_UNIT_FARAD;
212                 break;
213         case 0x08: /* 1000 mA DC */
214         case 0x09: /* 1001 A DC */
215         case 0x0a: /* 1010 mA AC+DC */
216         case 0x0b: /* 1011 A AC+DC */
217                 devc->mq = SR_MQ_CURRENT;
218                 devc->unit = SR_UNIT_AMPERE;
219                 devc->mqflags |= SR_MQFLAG_DC;
220                 if (ctmv >= 0x0a)
221                         devc->mqflags |= (SR_MQFLAG_AC | SR_MQFLAG_RMS);
222                 if ((ctmv == 0x08) || (ctmv == 0x0a))
223                         devc->scale1000 = -1;
224                 break;
225         case 0x0c: /* 1100 Hz */
226                 devc->mq = SR_MQ_FREQUENCY;
227                 devc->unit = SR_UNIT_HERTZ;
228                 break;
229         case 0x0d: /* 1101 dB */
230                 devc->mq = SR_MQ_VOLTAGE;
231                 devc->unit = SR_UNIT_DECIBEL_VOLT;
232                 devc->mqflags |= SR_MQFLAG_AC; /* dB available for AC only */
233                 break;
234         case 0x0e: /* 1110 Events AC, Events AC+DC. Actually delivers just
235                                 * current voltage via IR, nothing more. */
236                 devc->mq = SR_MQ_VOLTAGE;
237                 devc->unit = SR_UNIT_VOLT;
238                 devc->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS;
239                 break;
240         case 0x0f: /* 1111 Clock */
241                 devc->mq = SR_MQ_TIME;
242                 devc->unit = SR_UNIT_SECOND;
243                 devc->mqflags |= SR_MQFLAG_DURATION;
244                 break;
245         }
246 }
247
248 /**
249  * Decode range/sign/acdc byte special chars, Metrahit 18.
250  *
251  * @param[in] rs Rance/sign byte.
252  */
253 static void decode_rs_18(uint8_t rs, struct dev_context *devc)
254 {
255         int range;
256
257         /* Sign */
258         if (((devc->scale > 0) && (rs & 0x08)) ||
259                 ((devc->scale < 0) && !(rs & 0x08)))
260                 devc->scale *= -1.0;
261
262         /* Range */
263         range = rs & 0x07;
264         switch (devc->mq) {
265         case SR_MQ_VOLTAGE:
266                 if (devc->unit == SR_UNIT_DECIBEL_VOLT) {
267                         devc->scale *= pow(10.0, -2);
268                         /*
269                          * When entering relative mode, the device switches
270                          * from 10 byte to 6 byte msg format. Unfortunately
271                          * it switches back to 10 byte when the second value
272                          * is measured, so that's not sufficient to
273                          * identify relative mode.
274                          */
275                 }
276                 else if (devc->vmains_29S)
277                         devc->scale *= pow(10.0, range - 2);
278                 else
279                         devc->scale *= pow(10.0, range - 5);
280                 break;
281         case SR_MQ_CURRENT:
282                 if (devc->scale1000 == -1)
283                         devc->scale *= pow(10.0, range - 5);
284                 else
285                         devc->scale *= pow(10.0, range - 4);
286                 break;
287         case SR_MQ_RESISTANCE:
288                 devc->scale *= pow(10.0, range - 2);
289                 break;
290         case SR_MQ_FREQUENCY:
291                 devc->scale *= pow(10.0, range - 3);
292                 break;
293         case SR_MQ_TEMPERATURE:
294                 devc->scale *= pow(10.0, range - 2);
295                 break;
296         case SR_MQ_CAPACITANCE:
297                 devc->scale *= pow(10.0, range - 14);
298                 break;
299         /* TODO: 29S Mains measurements. */
300         }
301 }
302
303 /**
304  * Decode special chars, Metrahit 18.
305  *
306  * @param[in] spc Special characters 1 and 2 (s1 | (s2 << 4)).
307  */
308 static void decode_spc_18(uint8_t spc, struct dev_context *devc)
309 {
310         /* xxxx1xxx ZERO */
311         /* xxxxx1xx BEEP */
312         /* xxxxxx1x Low battery */
313         /* xxxxxxx1 Fuse */
314
315         if (devc->mq == SR_MQ_TIME) {
316                 /* xxx1xxxx Clock running: 1; stop: 0 */
317                 sr_spew("Clock running: %d", spc >> 4);
318         } else {
319                 /* 1xxxxxxx MAN */
320                 setmqf(devc, SR_MQFLAG_AUTORANGE, !(spc & 0x80));
321
322                 /* x1xxxxxx MIN */
323                 setmqf(devc, SR_MQFLAG_MIN, spc & 0x40);
324
325                 /* xx1xxxxx MAX */
326                 setmqf(devc, SR_MQFLAG_MAX, spc & 0x20);
327
328                 /* xxx1xxxx DATA */
329                 setmqf(devc, SR_MQFLAG_HOLD, spc & 0x10);
330         }
331 }
332
333 /**
334  * Decode current type and measured value, Metrahit 2x.
335  *
336  * @param[in] ctmv Current type and measured value (v1 | (v2 << 4)).
337  */
338 static void decode_ctmv_2x(uint8_t ctmv, struct dev_context *devc)
339 {
340         if ((ctmv > 0x1c) || (!devc)) {
341                 sr_err("decode_ctmv_2x(%d): invalid param(s)!", ctmv);
342                 return;
343         }
344
345         devc->mq = 0;
346         devc->unit = 0;
347         devc->mqflags = 0;
348
349         switch (ctmv) {
350         /* 00000 unused */
351         case 0x01: /* 00001 V DC */
352         case 0x02: /* 00010 V AC+DC */
353         case 0x03: /* 00011 V AC */
354                 devc->mq = SR_MQ_VOLTAGE;
355                 devc->unit = SR_UNIT_VOLT;
356                 if (ctmv <= 0x02)
357                         devc->mqflags |= SR_MQFLAG_DC;
358                 if (ctmv >= 0x02) {
359                         devc->mqflags |= SR_MQFLAG_AC;
360                         if (devc->model >= METRAHIT_24S)
361                                 devc->model |= SR_MQFLAG_RMS;
362                 }
363                 break;
364         case 0x04: /* 00100 mA DC */
365         case 0x05: /* 00101 mA AC+DC */
366                 devc->scale1000 = -1;
367         case 0x06: /* 00110 A DC */
368         case 0x07: /* 00111 A AC+DC */
369                 devc->mq = SR_MQ_CURRENT;
370                 devc->unit = SR_UNIT_AMPERE;
371                 devc->mqflags |= SR_MQFLAG_DC;
372                 if ((ctmv == 0x05) || (ctmv == 0x07)) {
373                         devc->mqflags |= SR_MQFLAG_AC;
374                         if (devc->model >= METRAHIT_24S)
375                                 devc->mqflags |= SR_MQFLAG_RMS;
376                 }
377                 break;
378         case 0x08: /* 01000 Ohm */
379                 devc->mq = SR_MQ_RESISTANCE;
380                 devc->unit = SR_UNIT_OHM;
381                 break;
382         case 0x09: /* 01001 F */
383                 devc->mq = SR_MQ_CAPACITANCE;
384                 devc->unit = SR_UNIT_FARAD;
385                 devc->scale *= 0.1;
386                 break;
387         case 0x0a: /* 01010 dB */
388                 devc->mq = SR_MQ_VOLTAGE;
389                 devc->unit = SR_UNIT_DECIBEL_VOLT;
390                 devc->mqflags |= SR_MQFLAG_AC;
391                 break;
392         case 0x0b: /* 01011 Hz U ACDC */
393         case 0x0c: /* 01100 Hz U AC */
394                 devc->mq = SR_MQ_FREQUENCY;
395                 devc->unit = SR_UNIT_HERTZ;
396                 devc->mqflags |= SR_MQFLAG_AC;
397                 if (ctmv <= 0x0b)
398                         devc->mqflags |= SR_MQFLAG_DC;
399                 break;
400         case 0x0d: /* 01101 W on power, mA range (29S only) */
401         case 0x0e: /* 01110 W on power, A range (29S only) */
402                 /* TODO: Differences between Send Mode and bidir protocol here */
403                 devc->mq = SR_MQ_POWER;
404                 devc->unit = SR_UNIT_WATT;
405                 break;
406         case 0x0f: /* 01111 Diode */
407         case 0x10: /* 10000 Diode with buzzer (actually cont. with voltage) */
408                 devc->unit = SR_UNIT_VOLT;
409                 if (ctmv == 0x0f) {
410                         devc->mq = SR_MQ_VOLTAGE;
411                         devc->mqflags |= SR_MQFLAG_DIODE;
412                         devc->scale *= 0.1;
413                 } else {
414                         devc->mq = SR_MQ_CONTINUITY;
415                         devc->scale *= 0.00001;
416                 }
417                 devc->unit = SR_UNIT_VOLT;
418                 break;
419         case 0x11: /* 10001 Ohm with buzzer */
420                 devc->mq = SR_MQ_CONTINUITY;
421                 devc->unit = SR_UNIT_OHM;
422                 devc->scale1000 = -1;
423                 break;
424         case 0x12: /* 10010 Temperature */
425                 devc->mq = SR_MQ_TEMPERATURE;
426                 devc->unit = SR_UNIT_CELSIUS;
427                 /* This can be Fahrenheit. That is detected by range=4 later. */
428                 break;
429         /* 0x13 10011, 0x14 10100 unsed */
430         case 0x15: /* 10101 Press (29S only) */
431                 /* TODO: What does that mean? Possibly phase shift?
432                    Then we need a unit/flag for it. */
433                 devc->mq = SR_MQ_GAIN;
434                 devc->unit = SR_UNIT_PERCENTAGE;
435                 break;
436         case 0x16: /* 10110 Pulse W (29S only) */
437                 /* TODO: Own unit and flag for this! */
438                 devc->mq = SR_MQ_POWER;
439                 devc->unit = SR_UNIT_WATT;
440                 break;
441         case 0x17: /* 10111 TRMS V on mains (29S only) */
442                 devc->mq = SR_MQ_VOLTAGE;
443                 devc->unit = SR_UNIT_VOLT;
444                 devc->mqflags |= (SR_MQFLAG_AC | SR_MQFLAG_RMS);
445                 devc->vmains_29S = TRUE;
446                 break;
447         case 0x18: /* 11000 Counter (zero crossings of a signal) */
448                 devc->mq = SR_MQ_VOLTAGE;
449                 devc->unit = SR_UNIT_UNITLESS;
450                 break;
451         case 0x19: /* 11001 Events U ACDC */
452         case 0x1a: /* 11010 Events U AC */
453                 /* TODO: No unit or flags for this yet! */
454                 devc->mq = SR_MQ_VOLTAGE;
455                 devc->unit = SR_UNIT_UNITLESS;
456                 devc->mqflags |= SR_MQFLAG_AC;
457                 if (ctmv <= 0x19)
458                         devc->mqflags |= SR_MQFLAG_DC;
459                 break;
460         case 0x1b: /* 11011 pulse on mains (29S only) */
461                 /* TODO: No unit or flags for this yet! */
462                 devc->mq = SR_MQ_VOLTAGE;
463                 devc->unit = SR_UNIT_UNITLESS;
464                 devc->mqflags |= SR_MQFLAG_AC;
465                 break;
466         case 0x1c: /* 11100 dropout on mains (29S only) */
467                 /* TODO: No unit or flags for this yet! */
468                 devc->mq = SR_MQ_VOLTAGE;
469                 devc->unit = SR_UNIT_UNITLESS;
470                 devc->mqflags |= SR_MQFLAG_AC;
471                 break;
472         default:
473                 sr_err("decode_ctmv_2x(%d, ...): Unknown ctmv!");
474                 break;
475         }
476 }
477
478 /**
479  * Decode range/sign/acdc byte special chars, Metrahit 2x.
480  *
481  * @param[in] rs Rance/sign byte.
482  */
483 static void decode_rs_2x(uint8_t rs, struct dev_context *devc)
484 {
485         int range;
486
487         /* Sign */
488         if (((devc->scale > 0) && (rs & 0x08)) ||
489                 ((devc->scale < 0) && !(rs & 0x08)))
490                 devc->scale *= -1.0;
491
492         /* Range */
493         range = rs & 0x07;
494         switch (devc->mq) {
495         case SR_MQ_VOLTAGE:
496                 if (devc->unit == SR_UNIT_DECIBEL_VOLT)
497                         devc->scale *= pow(10.0, -3);
498                 else if (devc->vmains_29S)
499                         devc->scale *= pow(10.0, range - 2);
500                 else if(devc->mqflags & SR_MQFLAG_AC)
501                         devc->scale *= pow(10.0, range - 6);
502                 else /* "Undocumented feature": Between AC and DC
503                         scaling differs by 1. */
504                         devc->scale *= pow(10.0, range - 5);
505                 break;
506         case SR_MQ_CURRENT:
507                 if (devc->scale1000 == -1)
508                         devc->scale *= pow(10.0, range - 5);
509                 else
510                         devc->scale *= pow(10.0, range - 4);
511                 break;
512         case SR_MQ_RESISTANCE:
513                 devc->scale *= pow(10.0, range - 3);
514                 break;
515         case SR_MQ_FREQUENCY:
516                 devc->scale *= pow(10.0, range - 3);
517                 break;
518         case SR_MQ_TEMPERATURE:
519                 if (range == 4) /* Indicator for °F */
520                         devc->unit = SR_UNIT_FAHRENHEIT;
521                 devc->scale *= pow(10.0, - 2);
522                 break;
523         case SR_MQ_CAPACITANCE:
524                 devc->scale *= pow(10.0, range - 13);
525                 break;
526         /* TODO: 29S Mains measurements. */
527         }
528 }
529
530 /**
531  * Decode special chars (Metrahit 2x).
532  *
533  * @param[in] spc Special characters 1 and 2 (s1 | (s2 << 4)).
534  */
535 static void decode_spc_2x(uint8_t spc, struct dev_context *devc)
536 {
537         /* xxxxxxx1 Fuse */
538
539         /* xxxxxx1x Low battery */
540
541         /* xxxxx1xx BEEP */
542
543         /* xxxx1xxx ZERO */
544
545         /* xxx1xxxx DATA */
546         setmqf(devc, SR_MQFLAG_HOLD, spc & 0x10);
547
548         /* x11xxxxx unused */
549         /* 1xxxxxxx MAN */
550         setmqf(devc, SR_MQFLAG_AUTORANGE, !(spc & 0x80));
551 }
552
553 /** Clean range and sign. */
554 static void clean_rs_v(struct dev_context *devc)
555 {
556         devc->value = 0.0;
557         devc->scale = 1.0;
558 }
559
560 /** Clean current type, measured variable, range and sign. */
561 static void clean_ctmv_rs_v(struct dev_context *devc)
562 {
563         devc->mq = 0;
564         devc->unit = 0;
565         devc->mqflags = 0;
566         devc->scale1000 = 0;
567         devc->vmains_29S = FALSE;
568         clean_rs_v(devc);
569 }
570
571 /** Send prepared value. */
572 static void send_value(struct sr_dev_inst *sdi)
573 {
574         struct dev_context *devc;
575         struct sr_datafeed_analog analog;
576         struct sr_datafeed_packet packet;
577
578         devc = sdi->priv;
579
580         memset(&analog, 0, sizeof(analog));
581         analog.probes = sdi->probes;
582         analog.num_samples = 1;
583         analog.mq = devc->mq;
584         analog.unit = devc->unit;
585         analog.mqflags = devc->mqflags;
586         analog.data = &devc->value;
587
588         memset(&packet, 0, sizeof(packet));
589         packet.type = SR_DF_ANALOG;
590         packet.payload = &analog;
591         sr_session_send(devc->cb_data, &packet);
592
593         devc->num_samples++;
594 }
595
596 /** Process 6-byte data message, Metrahit 1x/2x. */
597 static void process_msg_dta_6(struct sr_dev_inst *sdi)
598 {
599         struct dev_context *devc;
600         int cnt;
601         uint8_t dgt;
602
603         devc = sdi->priv;
604         clean_rs_v(devc);
605
606         /* Byte 0, range and sign */
607         if (devc->model <= METRAHIT_16X)
608                 decode_rs_16(bc(devc->buf[0]), devc);
609         else if (devc->model < METRAHIT_2X)
610                 decode_rs_18(bc(devc->buf[0]), devc);
611         else
612                 decode_rs_2x(bc(devc->buf[0]), devc);
613
614         /* Bytes 1-5, digits (ls first). */
615         for (cnt = 0; cnt < 5; cnt++) {
616                 dgt = bc(devc->buf[1 + cnt]);
617                 if (dgt >= 10) {
618                         /* 10 Overload; on model <= 16X also 11 possible. */
619                         devc->value = NAN;
620                         devc->scale = 1.0;
621                         break;
622                 }
623                 devc->value += pow(10.0, cnt) * dgt;
624         }
625         sr_spew("process_msg_dta_6() value=%f scale=%f scalet=%d",
626                 devc->value, devc->scale, devc->scale1000);
627         if (devc->value != NAN)
628                 devc->value *= devc->scale * pow(1000.0, devc->scale1000);
629
630         /* Create and send packet. */
631         send_value(sdi);
632 }
633
634 /** Process 5-byte info message, Metrahit 1x/2x. */
635 static void process_msg_inf_5(struct sr_dev_inst *sdi)
636 {
637         struct dev_context *devc;
638         enum model model;
639
640         devc = sdi->priv;
641
642         clean_ctmv_rs_v(devc);
643
644         /* Process byte 0 */
645         model = gmc_decode_model_sm(bc(devc->buf[0]));
646         if (model != devc->model) {
647                 sr_warn("Model mismatch in data: Detected %s, now %s",
648                         gmc_model_str(devc->model), gmc_model_str(model));
649         }
650
651         /* Process bytes 1-4 */
652         if (devc->model <= METRAHIT_16X) {
653                 decode_ctmv_16(bc(devc->buf[1]), devc);
654                 decode_spc_16(bc(devc->buf[2]) | (bc(devc->buf[3]) << 4), devc);
655                 decode_rs_16(bc(devc->buf[4]), devc);
656         } else if (devc->model <= METRAHIT_18S) {
657                 decode_ctmv_18(bc(devc->buf[1]), devc);
658                 decode_spc_18(bc(devc->buf[2]) | (bc(devc->buf[3]) << 4), devc);
659                 decode_rs_18(bc(devc->buf[4]), devc);
660         } else { /* Must be Metrahit 2x */
661                 decode_ctmv_2x(bc(devc->buf[1]), devc);
662                 decode_spc_2x(bc(devc->buf[2]) | (bc(devc->buf[3]) << 4), devc);
663                 decode_rs_2x(bc(devc->buf[4]), devc);
664         }
665 }
666
667 /** Process 10-byte info/data message, Metrahit 15+. */
668 static void process_msg_inf_10(struct sr_dev_inst *sdi)
669 {
670         struct dev_context *devc;
671         int cnt;
672         uint8_t dgt;
673
674         devc = sdi->priv;
675
676         process_msg_inf_5(sdi);
677
678         /* Now decode numbers */
679         for (cnt = 0; cnt < 5; cnt++) {
680                 dgt = bc(devc->buf[5 + cnt]);
681                 if (dgt >= 10) { /* Overload */
682                         devc->value = NAN;
683                         devc->scale = 1.0;
684                         break;
685                 }
686                 devc->value += pow(10.0, cnt) * dgt;
687         }
688         sr_spew("process_msg_inf_10() value=%f scale=%f scalet=%d",
689                         devc->value, devc->scale,  devc->scale1000);
690
691         if (devc->value != NAN)
692                 devc->value *= devc->scale * pow(1000.0, devc->scale1000);
693
694         /* Create and send packet. */
695         send_value(sdi);
696 }
697
698 /** Decode send interval (Metrahit 2x only). */
699 static const char *decode_send_interval(uint8_t si)
700 {
701         switch (si) {
702         case 0x00:
703                 return "0.05";
704         case 0x01:
705                 return "0.1";
706         case 0x02:
707                 return "0.2";
708         case 0x03:
709                 return "0.5";
710         case 0x04:
711                 return "00:01";
712         case 0x05:
713                 return "00:02";
714         case 0x06:
715                 return "00:05";
716         case 0x07:
717                 return "00:10";
718         case 0x08:
719                 return "00:20";
720         case 0x09:
721                 return "00:30";
722         case 0x0a:
723                 return "01:00";
724         case 0x0b:
725                 return "02:00";
726         case 0x0c:
727                 return "05:00";
728         case 0x0d:
729                 return "10:00";
730         case 0x0e:
731                 return "----";
732         case 0x0f:
733                 return "data";
734         default:
735                 return "Unknown value";
736         }
737 }
738
739 /** Process 13-byte info/data message, Metrahit 2x. */
740 static void process_msg_inf_13(struct sr_dev_inst *sdi)
741 {
742         struct dev_context *devc;
743         enum model model;
744         int cnt;
745         uint8_t dgt;
746
747         devc = sdi->priv;
748
749         clean_ctmv_rs_v(devc);
750
751         /* Byte 0, model. */
752         model = gmc_decode_model_sm(bc(devc->buf[0]));
753         if (model != devc->model) {
754                 sr_warn("Model mismatch in data: Detected %s, now %s",
755                         gmc_model_str(devc->model), gmc_model_str(model));
756         }
757
758         /* Bytes 1-4, 11. */
759         decode_ctmv_2x(bc(devc->buf[1]) | (bc(devc->buf[11]) << 4), devc);
760         decode_spc_2x(bc(devc->buf[2]) | (bc(devc->buf[3]) << 4), devc);
761         decode_rs_2x(bc(devc->buf[4]), devc);
762
763         /* Bytes 5-10, digits (ls first). */
764         for (cnt = 0; cnt < 6; cnt++) {
765                 dgt = bc(devc->buf[5 + cnt]);
766                 if (dgt == 10) { /* Overload */
767                         devc->value = NAN;
768                         devc->scale = 1.0;
769                         break;
770                 }
771                 devc->value += pow(10.0, cnt) * dgt;
772         }
773         sr_spew("process_msg_inf_13() value=%f scale=%f scale1000=%d mq=%d "
774                 "unit=%d mqflags=0x%02llx", devc->value, devc->scale,
775                 devc->scale1000, devc->mq, devc->unit, devc->mqflags);
776         if (devc->value != NAN)
777                 devc->value *= devc->scale * pow(1000.0, devc->scale1000);
778
779         /* Byte 12, Send Interval */
780         sr_spew("Send interval: %s", decode_send_interval(bc(devc->buf[12])));
781
782         /* Create and send packet. */
783         send_value(sdi);
784 }
785
786 SR_PRIV int gmc_mh_1x_2x_receive_data(int fd, int revents, void *cb_data)
787 {
788         struct sr_dev_inst *sdi;
789         struct dev_context *devc;
790         struct sr_serial_dev_inst *serial;
791         uint8_t buf, msgt;
792         int len;
793         gdouble elapsed_s;
794
795         (void)fd;
796
797         if (!(sdi = cb_data))
798                 return TRUE;
799
800         if (!(devc = sdi->priv))
801                 return TRUE;
802
803         serial = sdi->conn;
804
805         if (revents == G_IO_IN) { /* Serial data arrived. */
806                 while (GMC_BUFSIZE - devc->buflen - 1 > 0) {
807                         len = serial_read(serial, devc->buf + devc->buflen, 1);
808                         if (len < 1)
809                                 break;
810                         buf = *(devc->buf + devc->buflen);
811                         sr_spew("read 0x%02x/%d/%d", buf, buf, buf & MSGC_MASK);
812                         devc->buflen += len;
813                         if (!devc->settings_ok) {
814                                 /*
815                                  * If no device type/settings record processed
816                                  * yet, wait for one.
817                                  */
818                                 if ((devc->buf[0] & MSGID_MASK) != MSGID_INF) {
819                                         devc->buflen = 0;
820                                         continue;
821                                 }
822                                 devc->settings_ok = TRUE;
823                         }
824
825                         msgt = devc->buf[0] & MSGID_MASK;
826                         switch (msgt) {
827                         case MSGID_INF:
828                                 if (devc->buflen == 13) {
829                                         process_msg_inf_13(sdi);
830                                         devc->buflen = 0;
831                                         continue;
832                                 } else if ((devc->buflen == 10) &&
833                                          (devc->model <= METRAHIT_18S)) {
834                                         process_msg_inf_10(sdi);
835                                         devc->buflen = 0;
836                                         continue;
837                                 }
838                                 else if ((devc->buflen >= 5) &&
839                                         (devc->buf[devc->buflen - 1] &
840                                         MSGID_MASK) != MSGID_DATA) {
841                                         /*
842                                          * Char just received is beginning
843                                          * of next message.
844                                          */
845                                         process_msg_inf_5(sdi);
846                                         devc->buf[0] =
847                                                 devc->buf[devc->buflen - 1];
848                                         devc->buflen = 1;
849                                         continue;
850                                 }
851                                 break;
852                         case MSGID_DTA:
853                         case MSGID_D10:
854                                 if (devc->buflen == 6) {
855                                         process_msg_dta_6(sdi);
856                                         devc->buflen = 0;
857                                 }
858                                 break;
859                         case MSGID_DATA:
860                                 sr_err("Comm error, unexpected data byte!");
861                                 devc->buflen = 0;
862                                 break;
863                         }
864                 }
865         }
866
867         /* If number of samples or time limit reached, stop aquisition. */
868         if (devc->limit_samples && (devc->num_samples >= devc->limit_samples))
869                 sdi->driver->dev_acquisition_stop(sdi, cb_data);
870
871         if (devc->limit_msec) {
872                 elapsed_s = g_timer_elapsed(devc->elapsed_msec, NULL);
873                 if ((elapsed_s * 1000) >= devc->limit_msec)
874                         sdi->driver->dev_acquisition_stop(sdi, cb_data);
875         }
876
877         return TRUE;
878 }
879
880 /** Decode model in "send mode". */
881 SR_PRIV int gmc_decode_model_sm(uint8_t mcode)
882 {
883         if (mcode > 0xf) {
884                 sr_err("decode_model(%d): Model code 0..15 expected!", mcode);
885                 return METRAHIT_NONE;
886         }
887
888         switch(mcode) {
889         case 0x04: /* 0100b */
890                 return METRAHIT_12S;
891         case 0x08: /* 1000b */
892                 return METRAHIT_13S14A;
893         case 0x09: /* 1001b */
894                 return METRAHIT_14S;
895         case 0x0A: /* 1010b */
896                 return METRAHIT_15S;
897         case 0x0B: /* 1011b */
898                 return METRAHIT_16S;
899         case 0x06: /* 0110b (undocumented by GMC!) */
900                 return METRAHIT_16I;
901         case 0x0D: /* 1101b */
902                 return METRAHIT_18S;
903         case 0x02: /* 0010b */
904                 return METRAHIT_22SM;
905         case 0x03: /* 0011b */
906                 return METRAHIT_23S;
907         case 0x0f: /* 1111b */
908                 return METRAHIT_24S;
909         case 0x05: /* 0101b */
910                 return METRAHIT_25SM;
911         case 0x01: /* 0001b */
912                 return METRAHIT_26S;
913         case 0x0c: /* 1100b */
914                 return METRAHIT_28S;
915         case 0x0e: /* 1110b */
916                 return METRAHIT_29S;
917         default:
918                 sr_err("Unknown model code %d!", mcode);
919                 return METRAHIT_NONE;
920         }
921 }
922
923 /**
924  * Decode model in bidirectional mode.
925  *
926  * @param[in] mcode Model code.
927  *
928  * @return Model code.
929  */
930 SR_PRIV int gmc_decode_model_bidi(uint8_t mcode)
931 {
932         switch (mcode) {
933         case 2:
934                 return METRAHIT_22SM;
935         case 3:
936                 return METRAHIT_23S;
937         case 4:
938                 return METRAHIT_24S;
939         case 5:
940                 return METRAHIT_25SM;
941         case 1:
942                 return METRAHIT_26S;
943         case 12:
944                 return METRAHIT_28S;
945         case 14:
946                 return METRAHIT_29S;
947         default:
948                 sr_err("Unknown model code %d!", mcode);
949                 return METRAHIT_NONE;
950         }
951 }
952
953 SR_PRIV const char *gmc_model_str(enum model mcode)
954 {
955         switch (mcode) {
956         case METRAHIT_NONE:
957                 return "-uninitialized model variable-";
958         case METRAHIT_12S:
959                 return "METRAHit 12S";
960         case METRAHIT_13S14A:
961                 return "METRAHit 13S/14A";
962         case METRAHIT_14S:
963                 return "METRAHit 14S";
964         case METRAHIT_15S:
965                 return "METRAHit 15S";
966         case METRAHIT_16S:
967                 return "METRAHit 16S";
968         case METRAHIT_16I:
969                 return "METRAHit 16I";
970         case METRAHIT_18S:
971                 return "METRAHit 18S";
972         case METRAHIT_22SM:
973                 return "METRAHit 22S/M";
974         case METRAHIT_23S:
975                 return "METRAHit 23S";
976         case METRAHIT_24S:
977                 return "METRAHit 24S";
978         case METRAHIT_25SM:
979                 return "METRAHit 25S/M";
980         case METRAHIT_26S:
981                 return "METRAHit 26S";
982         case METRAHIT_28S:
983                 return "METRAHit 28S";
984         case METRAHIT_29S:
985                 return "METRAHit 29S";
986         default:
987                 return "Unknown model code";
988         }
989 }