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