]> sigrok.org Git - libsigrok.git/blame - hardware/gmc-mh-1x-2x/protocol.c
serial-dmm: Increase timeout when scanning for DMMs.
[libsigrok.git] / hardware / gmc-mh-1x-2x / protocol.c
CommitLineData
7b4edcb6
MH
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
f5792417
MH
20#include <math.h>
21#include <string.h>
7b4edcb6
MH
22#include "protocol.h"
23
f5792417
MH
24/** Set or clear flags in devc->mqflags. */
25static 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
fc348b77
UH
33/** Decode current type and measured value, Metrahit 12-16. */
34static void decode_ctmv_16(uint8_t ctmv, struct dev_context *devc)
f5792417
MH
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;
873e0c12 54 if (devc->model >= METRAHIT_16S)
f5792417 55 devc->mqflags |= SR_MQFLAG_RMS;
fc348b77 56 }
f5792417
MH
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;
873e0c12 95 if (devc->model == METRAHIT_16S)
f5792417
MH
96 devc->mqflags |= SR_MQFLAG_RMS;
97 /* 16I A only with clamp, RMS questionable. */
98 break;
99 }
100}
101
fc348b77
UH
102/**
103 * Decode range/sign/acdc byte special chars (Metrahit 12-16).
104 *
105 * @param[in] spc Special characters 1 and 2 (s1 | (s2 << 4)).
f5792417 106 */
fc348b77 107static void decode_rs_16(uint8_t rs, struct dev_context *devc)
f5792417
MH
108{
109 sr_spew("decode_rs_16(%d) scale = %f", rs, devc->scale);
110
111 if (rs & 0x08) /* Sign */
112 devc->scale *= -1.0;
113
114 if (devc->mq == SR_MQ_CURRENT) {
115 if (rs & 0x04) /* 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:
fc348b77 123 if (devc->mq == SR_MQ_VOLTAGE) /* V */
f5792417
MH
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;
42f2f8a5 133 } else if (devc->scale1000 == 2) {
f5792417
MH
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
fc348b77
UH
151/**
152 * Decode special chars, Metrahit 12-16.
153 *
154 * @param[in] spc Special characters 1 and 2 (s1 | (s2 << 4)).
f5792417 155 */
fc348b77 156static void decode_spc_16(uint8_t spc, struct dev_context *devc)
f5792417
MH
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
fc348b77
UH
176/** Decode current type and measured value, Metrahit 18. */
177static void decode_ctmv_18(uint8_t ctmv, struct dev_context *devc)
f5792417
MH
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;
fc348b77 200 case 0x05: /* 0101 Diode/Diode with buzzer */
f5792417
MH
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
fc348b77
UH
248/**
249 * Decode range/sign/acdc byte special chars, Metrahit 18.
250 *
251 * @param[in] rs Rance/sign byte.
f5792417 252 */
fc348b77 253static void decode_rs_18(uint8_t rs, struct dev_context *devc)
f5792417
MH
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);
fc348b77
UH
268 /*
269 * When entering relative mode, the device switches
f5792417
MH
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
fc348b77
UH
303/**
304 * Decode special chars, Metrahit 18.
305 *
306 * @param[in] spc Special characters 1 and 2 (s1 | (s2 << 4)).
f5792417 307 */
fc348b77 308static void decode_spc_18(uint8_t spc, struct dev_context *devc)
f5792417
MH
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);
fc348b77 318 } else {
f5792417
MH
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
fc348b77
UH
333/**
334 * Decode current type and measured value, Metrahit 2x.
335 *
336 * @param[in] ctmv Current type and measured value (v1 | (v2 << 4)).
f5792417 337 */
fc348b77 338static void decode_ctmv_2x(uint8_t ctmv, struct dev_context *devc)
f5792417
MH
339{
340 if ((ctmv > 0x1c) || (!devc)) {
fc348b77 341 sr_err("decode_ctmv_2x(%d): invalid param(s)!", ctmv);
f5792417
MH
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;
873e0c12 360 if (devc->model >= METRAHIT_24S)
f5792417
MH
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;
873e0c12 374 if (devc->model >= METRAHIT_24S)
f5792417
MH
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;
fc348b77 413 } else {
f5792417
MH
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!");
fc348b77 474 break;
f5792417
MH
475 }
476}
477
fc348b77
UH
478/**
479 * Decode range/sign/acdc byte special chars, Metrahit 2x.
480 *
481 * @param[in] rs Rance/sign byte.
f5792417 482 */
fc348b77 483static void decode_rs_2x(uint8_t rs, struct dev_context *devc)
f5792417 484{
fc348b77 485 int range;
f5792417
MH
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:
fc348b77 496 if (devc->unit == SR_UNIT_DECIBEL_VOLT)
f5792417 497 devc->scale *= pow(10.0, -3);
f5792417
MH
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:
fc348b77 519 if (range == 4) /* Indicator for °F */
f5792417 520 devc->unit = SR_UNIT_FAHRENHEIT;
f5792417
MH
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
fc348b77
UH
530/**
531 * Decode special chars (Metrahit 2x).
532 *
533 * @param[in] spc Special characters 1 and 2 (s1 | (s2 << 4)).
f5792417 534 */
fc348b77 535static void decode_spc_2x(uint8_t spc, struct dev_context *devc)
f5792417
MH
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. */
554static 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. */
561static 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. */
572static 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. */
597static void process_msg_dta_6(struct sr_dev_inst *sdi)
598{
599 struct dev_context *devc;
600 int cnt;
fc348b77 601 uint8_t dgt;
f5792417
MH
602
603 devc = sdi->priv;
604 clean_rs_v(devc);
605
606 /* Byte 0, range and sign */
873e0c12 607 if (devc->model <= METRAHIT_16X)
f5792417 608 decode_rs_16(bc(devc->buf[0]), devc);
873e0c12 609 else if (devc->model < METRAHIT_2X)
f5792417 610 decode_rs_18(bc(devc->buf[0]), devc);
fc348b77 611 else
f5792417 612 decode_rs_2x(bc(devc->buf[0]), devc);
f5792417
MH
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. */
635static 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 */
873e0c12 645 model = gmc_decode_model_sm(bc(devc->buf[0]));
f5792417
MH
646 if (model != devc->model) {
647 sr_warn("Model mismatch in data: Detected %s, now %s",
873e0c12 648 gmc_model_str(devc->model), gmc_model_str(model));
f5792417
MH
649 }
650
651 /* Process bytes 1-4 */
873e0c12 652 if (devc->model <= METRAHIT_16X) {
f5792417
MH
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);
873e0c12 656 } else if (devc->model <= METRAHIT_18S) {
f5792417
MH
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);
fc348b77 660 } else { /* Must be Metrahit 2x */
f5792417
MH
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+. */
668static void process_msg_inf_10(struct sr_dev_inst *sdi)
669{
670 struct dev_context *devc;
671 int cnt;
fc348b77 672 uint8_t dgt;
f5792417
MH
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). */
fc348b77 699static const char *decode_send_interval(uint8_t si)
f5792417
MH
700{
701 switch (si) {
fc348b77
UH
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";
f5792417
MH
736 }
737}
738
739/** Process 13-byte info/data message, Metrahit 2x. */
740static void process_msg_inf_13(struct sr_dev_inst *sdi)
741{
742 struct dev_context *devc;
743 enum model model;
744 int cnt;
fc348b77 745 uint8_t dgt;
f5792417
MH
746
747 devc = sdi->priv;
748
749 clean_ctmv_rs_v(devc);
750
751 /* Byte 0, model. */
873e0c12 752 model = gmc_decode_model_sm(bc(devc->buf[0]));
f5792417
MH
753 if (model != devc->model) {
754 sr_warn("Model mismatch in data: Detected %s, now %s",
873e0c12 755 gmc_model_str(devc->model), gmc_model_str(model));
f5792417
MH
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
7b4edcb6
MH
786SR_PRIV int gmc_mh_1x_2x_receive_data(int fd, int revents, void *cb_data)
787{
f5792417 788 struct sr_dev_inst *sdi;
7b4edcb6 789 struct dev_context *devc;
f5792417 790 struct sr_serial_dev_inst *serial;
fc348b77 791 uint8_t buf, msgt;
f5792417 792 int len;
fc348b77 793 gdouble elapsed_s;
7b4edcb6
MH
794
795 (void)fd;
796
797 if (!(sdi = cb_data))
798 return TRUE;
799
800 if (!(devc = sdi->priv))
801 return TRUE;
802
f5792417
MH
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) {
fc348b77
UH
814 /*
815 * If no device type/settings record processed
816 * yet, wait for one.
817 */
f5792417
MH
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;
fc348b77 832 } else if ((devc->buflen == 10) &&
873e0c12 833 (devc->model <= METRAHIT_18S)) {
f5792417
MH
834 process_msg_inf_10(sdi);
835 devc->buflen = 0;
836 continue;
837 }
838 else if ((devc->buflen >= 5) &&
fc348b77 839 (devc->buf[devc->buflen - 1] &
f5792417 840 MSGID_MASK) != MSGID_DATA) {
fc348b77
UH
841 /*
842 * Char just received is beginning
843 * of next message.
844 */
f5792417 845 process_msg_inf_5(sdi);
fc348b77
UH
846 devc->buf[0] =
847 devc->buf[devc->buflen - 1];
f5792417
MH
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. */
fc348b77 868 if (devc->limit_samples && (devc->num_samples >= devc->limit_samples))
f5792417 869 sdi->driver->dev_acquisition_stop(sdi, cb_data);
f5792417
MH
870
871 if (devc->limit_msec) {
fc348b77
UH
872 elapsed_s = g_timer_elapsed(devc->elapsed_msec, NULL);
873 if ((elapsed_s * 1000) >= devc->limit_msec)
f5792417 874 sdi->driver->dev_acquisition_stop(sdi, cb_data);
7b4edcb6
MH
875 }
876
877 return TRUE;
878}
f5792417 879
fc348b77 880/** Decode model in "send mode". */
873e0c12 881SR_PRIV int gmc_decode_model_sm(uint8_t mcode)
f5792417
MH
882{
883 if (mcode > 0xf) {
884 sr_err("decode_model(%d): Model code 0..15 expected!", mcode);
873e0c12 885 return METRAHIT_NONE;
f5792417
MH
886 }
887
888 switch(mcode) {
fc348b77 889 case 0x04: /* 0100b */
873e0c12 890 return METRAHIT_12S;
fc348b77 891 case 0x08: /* 1000b */
873e0c12 892 return METRAHIT_13S14A;
fc348b77 893 case 0x09: /* 1001b */
873e0c12 894 return METRAHIT_14S;
fc348b77 895 case 0x0A: /* 1010b */
873e0c12 896 return METRAHIT_15S;
fc348b77 897 case 0x0B: /* 1011b */
873e0c12 898 return METRAHIT_16S;
fc348b77 899 case 0x06: /* 0110b (undocumented by GMC!) */
873e0c12 900 return METRAHIT_16I;
fc348b77 901 case 0x0D: /* 1101b */
873e0c12 902 return METRAHIT_18S;
fc348b77 903 case 0x02: /* 0010b */
873e0c12 904 return METRAHIT_22SM;
fc348b77 905 case 0x03: /* 0011b */
873e0c12 906 return METRAHIT_23S;
fc348b77 907 case 0x0f: /* 1111b */
873e0c12 908 return METRAHIT_24S;
fc348b77 909 case 0x05: /* 0101b */
873e0c12 910 return METRAHIT_25SM;
fc348b77 911 case 0x01: /* 0001b */
873e0c12 912 return METRAHIT_26S;
fc348b77 913 case 0x0c: /* 1100b */
873e0c12 914 return METRAHIT_28S;
fc348b77 915 case 0x0e: /* 1110b */
873e0c12 916 return METRAHIT_29S;
f5792417
MH
917 default:
918 sr_err("Unknown model code %d!", mcode);
873e0c12 919 return METRAHIT_NONE;
f5792417
MH
920 }
921}
922
fc348b77
UH
923/**
924 * Decode model in bidirectional mode.
925 *
926 * @param[in] mcode Model code.
927 *
928 * @return Model code.
929 */
873e0c12 930SR_PRIV int gmc_decode_model_bidi(uint8_t mcode)
f5792417 931{
fc348b77
UH
932 switch (mcode) {
933 case 2:
873e0c12 934 return METRAHIT_22SM;
fc348b77 935 case 3:
873e0c12 936 return METRAHIT_23S;
fc348b77 937 case 4:
873e0c12 938 return METRAHIT_24S;
fc348b77 939 case 5:
873e0c12 940 return METRAHIT_25SM;
fc348b77 941 case 1:
873e0c12 942 return METRAHIT_26S;
fc348b77 943 case 12:
873e0c12 944 return METRAHIT_28S;
fc348b77 945 case 14:
873e0c12 946 return METRAHIT_29S;
f5792417
MH
947 default:
948 sr_err("Unknown model code %d!", mcode);
873e0c12 949 return METRAHIT_NONE;
f5792417
MH
950 }
951}
952
873e0c12 953SR_PRIV const char *gmc_model_str(enum model mcode)
f5792417
MH
954{
955 switch (mcode) {
873e0c12 956 case METRAHIT_NONE:
f5792417 957 return "-uninitialized model variable-";
873e0c12 958 case METRAHIT_12S:
f5792417 959 return "METRAHit 12S";
873e0c12 960 case METRAHIT_13S14A:
f5792417 961 return "METRAHit 13S/14A";
873e0c12 962 case METRAHIT_14S:
f5792417 963 return "METRAHit 14S";
873e0c12 964 case METRAHIT_15S:
f5792417 965 return "METRAHit 15S";
873e0c12 966 case METRAHIT_16S:
f5792417 967 return "METRAHit 16S";
873e0c12 968 case METRAHIT_16I:
f5792417 969 return "METRAHit 16I";
873e0c12 970 case METRAHIT_18S:
f5792417 971 return "METRAHit 18S";
873e0c12 972 case METRAHIT_22SM:
f5792417 973 return "METRAHit 22S/M";
873e0c12 974 case METRAHIT_23S:
f5792417 975 return "METRAHit 23S";
873e0c12 976 case METRAHIT_24S:
f5792417 977 return "METRAHit 24S";
873e0c12 978 case METRAHIT_25SM:
f5792417 979 return "METRAHit 25S/M";
873e0c12 980 case METRAHIT_26S:
f5792417 981 return "METRAHit 26S";
873e0c12 982 case METRAHIT_28S:
f5792417 983 return "METRAHit 28S";
873e0c12 984 case METRAHIT_29S:
f5792417
MH
985 return "METRAHit 29S";
986 default:
987 return "Unknown model code";
988 }
989}