]> sigrok.org Git - libsigrok.git/blame - hardware/gmc-mh-1x-2x/protocol.c
gmc-mh-1x-2x: Cosmetics, whitespace, cleanups.
[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;
54 if (devc->model >= SR_METRAHIT_16S)
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;
95 if (devc->model == SR_METRAHIT_16S)
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;
fc348b77 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;
360 if (devc->model >= SR_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 >= SR_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;
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 */
fc348b77 607 if (devc->model <= SR_METRAHIT_16X)
f5792417 608 decode_rs_16(bc(devc->buf[0]), devc);
fc348b77 609 else if (devc->model < SR_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 */
645 model = sr_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 sr_gmc_model_str(devc->model),
649 sr_gmc_model_str(model));
650 }
651
652 /* Process bytes 1-4 */
653 if (devc->model <= SR_METRAHIT_16X) {
654 decode_ctmv_16(bc(devc->buf[1]), devc);
655 decode_spc_16(bc(devc->buf[2]) | (bc(devc->buf[3]) << 4), devc);
656 decode_rs_16(bc(devc->buf[4]), devc);
fc348b77 657 } else if (devc->model <= SR_METRAHIT_18S) {
f5792417
MH
658 decode_ctmv_18(bc(devc->buf[1]), devc);
659 decode_spc_18(bc(devc->buf[2]) | (bc(devc->buf[3]) << 4), devc);
660 decode_rs_18(bc(devc->buf[4]), devc);
fc348b77 661 } else { /* Must be Metrahit 2x */
f5792417
MH
662 decode_ctmv_2x(bc(devc->buf[1]), devc);
663 decode_spc_2x(bc(devc->buf[2]) | (bc(devc->buf[3]) << 4), devc);
664 decode_rs_2x(bc(devc->buf[4]), devc);
665 }
666}
667
668/** Process 10-byte info/data message, Metrahit 15+. */
669static void process_msg_inf_10(struct sr_dev_inst *sdi)
670{
671 struct dev_context *devc;
672 int cnt;
fc348b77 673 uint8_t dgt;
f5792417
MH
674
675 devc = sdi->priv;
676
677 process_msg_inf_5(sdi);
678
679 /* Now decode numbers */
680 for (cnt = 0; cnt < 5; cnt++) {
681 dgt = bc(devc->buf[5 + cnt]);
682 if (dgt >= 10) { /* Overload */
683 devc->value = NAN;
684 devc->scale = 1.0;
685 break;
686 }
687 devc->value += pow(10.0, cnt) * dgt;
688 }
689 sr_spew("process_msg_inf_10() value=%f scale=%f scalet=%d",
690 devc->value, devc->scale, devc->scale1000);
691
692 if (devc->value != NAN)
693 devc->value *= devc->scale * pow(1000.0, devc->scale1000);
694
695 /* Create and send packet. */
696 send_value(sdi);
697}
698
699/** Decode send interval (Metrahit 2x only). */
fc348b77 700static const char *decode_send_interval(uint8_t si)
f5792417
MH
701{
702 switch (si) {
fc348b77
UH
703 case 0x00:
704 return "0.05";
705 case 0x01:
706 return "0.1";
707 case 0x02:
708 return "0.2";
709 case 0x03:
710 return "0.5";
711 case 0x04:
712 return "00:01";
713 case 0x05:
714 return "00:02";
715 case 0x06:
716 return "00:05";
717 case 0x07:
718 return "00:10";
719 case 0x08:
720 return "00:20";
721 case 0x09:
722 return "00:30";
723 case 0x0a:
724 return "01:00";
725 case 0x0b:
726 return "02:00";
727 case 0x0c:
728 return "05:00";
729 case 0x0d:
730 return "10:00";
731 case 0x0e:
732 return "----";
733 case 0x0f:
734 return "data";
735 default:
736 return "Unknown value";
f5792417
MH
737 }
738}
739
740/** Process 13-byte info/data message, Metrahit 2x. */
741static void process_msg_inf_13(struct sr_dev_inst *sdi)
742{
743 struct dev_context *devc;
744 enum model model;
745 int cnt;
fc348b77 746 uint8_t dgt;
f5792417
MH
747
748 devc = sdi->priv;
749
750 clean_ctmv_rs_v(devc);
751
752 /* Byte 0, model. */
753 model = sr_gmc_decode_model_sm(bc(devc->buf[0]));
754 if (model != devc->model) {
755 sr_warn("Model mismatch in data: Detected %s, now %s",
756 sr_gmc_model_str(devc->model),
757 sr_gmc_model_str(model));
758 }
759
760 /* Bytes 1-4, 11. */
761 decode_ctmv_2x(bc(devc->buf[1]) | (bc(devc->buf[11]) << 4), devc);
762 decode_spc_2x(bc(devc->buf[2]) | (bc(devc->buf[3]) << 4), devc);
763 decode_rs_2x(bc(devc->buf[4]), devc);
764
765 /* Bytes 5-10, digits (ls first). */
766 for (cnt = 0; cnt < 6; cnt++) {
767 dgt = bc(devc->buf[5 + cnt]);
768 if (dgt == 10) { /* Overload */
769 devc->value = NAN;
770 devc->scale = 1.0;
771 break;
772 }
773 devc->value += pow(10.0, cnt) * dgt;
774 }
775 sr_spew("process_msg_inf_13() value=%f scale=%f scale1000=%d mq=%d "
776 "unit=%d mqflags=0x%02llx", devc->value, devc->scale,
777 devc->scale1000, devc->mq, devc->unit, devc->mqflags);
778 if (devc->value != NAN)
779 devc->value *= devc->scale * pow(1000.0, devc->scale1000);
780
781 /* Byte 12, Send Interval */
782 sr_spew("Send interval: %s", decode_send_interval(bc(devc->buf[12])));
783
784 /* Create and send packet. */
785 send_value(sdi);
786}
787
7b4edcb6
MH
788SR_PRIV int gmc_mh_1x_2x_receive_data(int fd, int revents, void *cb_data)
789{
f5792417 790 struct sr_dev_inst *sdi;
7b4edcb6 791 struct dev_context *devc;
f5792417 792 struct sr_serial_dev_inst *serial;
fc348b77 793 uint8_t buf, msgt;
f5792417 794 int len;
fc348b77 795 gdouble elapsed_s;
7b4edcb6
MH
796
797 (void)fd;
798
799 if (!(sdi = cb_data))
800 return TRUE;
801
802 if (!(devc = sdi->priv))
803 return TRUE;
804
f5792417
MH
805 serial = sdi->conn;
806
807 if (revents == G_IO_IN) { /* Serial data arrived. */
808 while (GMC_BUFSIZE - devc->buflen - 1 > 0) {
809 len = serial_read(serial, devc->buf + devc->buflen, 1);
810 if (len < 1)
811 break;
812 buf = *(devc->buf + devc->buflen);
813 sr_spew("read 0x%02x/%d/%d", buf, buf, buf & MSGC_MASK);
814 devc->buflen += len;
815 if (!devc->settings_ok) {
fc348b77
UH
816 /*
817 * If no device type/settings record processed
818 * yet, wait for one.
819 */
f5792417
MH
820 if ((devc->buf[0] & MSGID_MASK) != MSGID_INF) {
821 devc->buflen = 0;
822 continue;
823 }
824 devc->settings_ok = TRUE;
825 }
826
827 msgt = devc->buf[0] & MSGID_MASK;
828 switch (msgt) {
829 case MSGID_INF:
830 if (devc->buflen == 13) {
831 process_msg_inf_13(sdi);
832 devc->buflen = 0;
833 continue;
fc348b77 834 } else if ((devc->buflen == 10) &&
f5792417
MH
835 (devc->model <= SR_METRAHIT_18S)) {
836 process_msg_inf_10(sdi);
837 devc->buflen = 0;
838 continue;
839 }
840 else if ((devc->buflen >= 5) &&
fc348b77 841 (devc->buf[devc->buflen - 1] &
f5792417 842 MSGID_MASK) != MSGID_DATA) {
fc348b77
UH
843 /*
844 * Char just received is beginning
845 * of next message.
846 */
f5792417 847 process_msg_inf_5(sdi);
fc348b77
UH
848 devc->buf[0] =
849 devc->buf[devc->buflen - 1];
f5792417
MH
850 devc->buflen = 1;
851 continue;
852 }
853 break;
854 case MSGID_DTA:
855 case MSGID_D10:
856 if (devc->buflen == 6) {
857 process_msg_dta_6(sdi);
858 devc->buflen = 0;
859 }
860 break;
861 case MSGID_DATA:
862 sr_err("Comm error, unexpected data byte!");
863 devc->buflen = 0;
864 break;
865 }
866 }
867 }
868
869 /* If number of samples or time limit reached, stop aquisition. */
fc348b77 870 if (devc->limit_samples && (devc->num_samples >= devc->limit_samples))
f5792417 871 sdi->driver->dev_acquisition_stop(sdi, cb_data);
f5792417
MH
872
873 if (devc->limit_msec) {
fc348b77
UH
874 elapsed_s = g_timer_elapsed(devc->elapsed_msec, NULL);
875 if ((elapsed_s * 1000) >= devc->limit_msec)
f5792417 876 sdi->driver->dev_acquisition_stop(sdi, cb_data);
7b4edcb6
MH
877 }
878
879 return TRUE;
880}
f5792417 881
fc348b77
UH
882/** Decode model in "send mode". */
883SR_PRIV int sr_gmc_decode_model_sm(uint8_t mcode)
f5792417
MH
884{
885 if (mcode > 0xf) {
886 sr_err("decode_model(%d): Model code 0..15 expected!", mcode);
887 return SR_METRAHIT_NONE;
888 }
889
890 switch(mcode) {
fc348b77 891 case 0x04: /* 0100b */
f5792417 892 return SR_METRAHIT_12S;
fc348b77 893 case 0x08: /* 1000b */
f5792417 894 return SR_METRAHIT_13S14A;
fc348b77 895 case 0x09: /* 1001b */
f5792417 896 return SR_METRAHIT_14S;
fc348b77 897 case 0x0A: /* 1010b */
f5792417 898 return SR_METRAHIT_15S;
fc348b77 899 case 0x0B: /* 1011b */
f5792417 900 return SR_METRAHIT_16S;
fc348b77 901 case 0x06: /* 0110b (undocumented by GMC!) */
f5792417 902 return SR_METRAHIT_16I;
fc348b77 903 case 0x0D: /* 1101b */
f5792417 904 return SR_METRAHIT_18S;
fc348b77 905 case 0x02: /* 0010b */
f5792417 906 return SR_METRAHIT_22SM;
fc348b77 907 case 0x03: /* 0011b */
f5792417 908 return SR_METRAHIT_23S;
fc348b77 909 case 0x0f: /* 1111b */
f5792417 910 return SR_METRAHIT_24S;
fc348b77 911 case 0x05: /* 0101b */
f5792417 912 return SR_METRAHIT_25SM;
fc348b77 913 case 0x01: /* 0001b */
f5792417 914 return SR_METRAHIT_26S;
fc348b77 915 case 0x0c: /* 1100b */
f5792417 916 return SR_METRAHIT_28S;
fc348b77 917 case 0x0e: /* 1110b */
f5792417
MH
918 return SR_METRAHIT_29S;
919 default:
920 sr_err("Unknown model code %d!", mcode);
921 return SR_METRAHIT_NONE;
922 }
923}
924
fc348b77
UH
925/**
926 * Decode model in bidirectional mode.
927 *
928 * @param[in] mcode Model code.
929 *
930 * @return Model code.
931 */
932SR_PRIV int sr_gmc_decode_model_bidi(uint8_t mcode)
f5792417 933{
fc348b77
UH
934 switch (mcode) {
935 case 2:
936 return SR_METRAHIT_22SM;
937 case 3:
938 return SR_METRAHIT_23S;
939 case 4:
940 return SR_METRAHIT_24S;
941 case 5:
942 return SR_METRAHIT_25SM;
943 case 1:
944 return SR_METRAHIT_26S;
945 case 12:
946 return SR_METRAHIT_28S;
947 case 14:
948 return SR_METRAHIT_29S;
f5792417
MH
949 default:
950 sr_err("Unknown model code %d!", mcode);
951 return SR_METRAHIT_NONE;
952 }
953}
954
fc348b77 955SR_PRIV const char *sr_gmc_model_str(enum model mcode)
f5792417
MH
956{
957 switch (mcode) {
958 case SR_METRAHIT_NONE:
959 return "-uninitialized model variable-";
960 case SR_METRAHIT_12S:
961 return "METRAHit 12S";
962 case SR_METRAHIT_13S14A:
963 return "METRAHit 13S/14A";
964 case SR_METRAHIT_14S:
965 return "METRAHit 14S";
966 case SR_METRAHIT_15S:
967 return "METRAHit 15S";
968 case SR_METRAHIT_16S:
969 return "METRAHit 16S";
970 case SR_METRAHIT_16I:
971 return "METRAHit 16I";
972 case SR_METRAHIT_18S:
973 return "METRAHit 18S";
974 case SR_METRAHIT_22SM:
975 return "METRAHit 22S/M";
976 case SR_METRAHIT_23S:
977 return "METRAHit 23S";
978 case SR_METRAHIT_24S:
979 return "METRAHit 24S";
980 case SR_METRAHIT_25SM:
981 return "METRAHit 25S/M";
982 case SR_METRAHIT_26S:
983 return "METRAHit 26S";
984 case SR_METRAHIT_28S:
985 return "METRAHit 28S";
986 case SR_METRAHIT_29S:
987 return "METRAHit 29S";
988 default:
989 return "Unknown model code";
990 }
991}