+ clean_ctmv_rs_v(devc);
+ addr = devc->buf[0] & MASK_6BITS;
+ if (addr != devc->addr)
+ sr_info("Device address mismatch %d/%d!", addr, devc->addr);
+
+ switch (devc->buf[3]) { /* That's the command this reply is for */
+ /* 0 cannot occur, the respective message is not a 14-byte message */
+ case 1: /* Read first free and occupied address */
+ sr_spew("Cmd %d unimplemented!", devc->buf[3]);
+ break;
+ case 2: /* Clear all RAM in multimeter */
+ sr_spew("Cmd %d unimplemented!", devc->buf[3]);
+ break;
+ case 3: /* Read firmware version and status */
+ sr_spew("Cmd 3, Read firmware and status", devc->buf[3]);
+ switch (devc->cmd_idx) {
+ case 0:
+ devc->fw_ver_maj = devc->buf[5];
+ devc->fw_ver_min = devc->buf[4];
+ sr_spew("Firmware version %d.%d", (int)devc->fw_ver_maj, (int)devc->fw_ver_min);
+ sr_spew("Rotary Switch Position (1..10): %d", (int)devc->buf[6]);
+ /** Docs say values 0..9, but that's not true */
+ sr_spew("Measurement Function: %d ", (int)devc->buf[7]);
+ decode_ctmv_2x(devc->buf[7], devc);
+ sr_spew("Range: 0x%x", devc->buf[8]);
+ decode_rs_2x_TR2(devc->buf[8] & 0x0f, devc); /* Docs wrong, uses conversion table TR_2! */
+ devc->autorng = (devc->buf[8] & 0x20) == 0;
+ // TODO 9, 10: 29S special functions
+ devc->ubatt = 0.1 * (float)devc->buf[11];
+ devc->model = gmc_decode_model_bd(devc->buf[12]);
+ sr_spew("Model=%s, battery voltage=%2.1f V", gmc_model_str(devc->model), (double)devc->ubatt);
+ break;
+ case 1:
+ sr_spew("Internal version %d.%d", (int)devc->buf[5], (int)devc->buf[4]);
+ sr_spew("Comm mode: 0x%x", (int)devc->buf[6]);
+ sr_spew("Block cnt%%64: %d", (int)devc->buf[7]);
+ sr_spew("drpCi: %d drpCh: %d", (int)devc->buf[8], (int)devc->buf[9]);
+ // Semantics undocumented. Possibly Metrahit 29S dropouts stuff?
+ break;
+ default:
+ sr_spew("Cmd 3: Unknown cmd_idx=%d", devc->cmd_idx);
+ break;
+ }
+ break;
+ case 4: /* Set real time, date, sample rate, trigger, ... */
+ sr_spew("Cmd %d unimplemented!", devc->buf[3]);
+ break;
+ case 5: /* Read real time, date, sample rate, trigger... */
+ sr_spew("Cmd %d unimplemented!", devc->buf[3]);
+ break;
+ case 6: /* Set modes or power off */
+ sr_spew("Cmd %d unimplemented!", devc->buf[3]);
+ break;
+ case 7: /* Set measurement function, range, autom/man. */
+ sr_spew("Cmd %d unimplemented!", devc->buf[3]);
+ break;
+ case 8: /* Get one measurement value */
+ sr_spew("Cmd 8, get one measurement value");
+ sr_spew("Measurement Function: %d ", (int)devc->buf[5]);
+ decode_ctmv_2x(devc->buf[5], devc);
+ if (!(devc->buf[6] & 0x10)) /* If bit4=0, old data. */
+ return SR_OK;
+
+ decode_rs_2x_TR2(devc->buf[6] & 0x0f, devc); // The docs say conversion table TR_3, but that does not work
+ setmqf(devc, SR_MQFLAG_AUTORANGE, devc->autorng);
+ /* 6 digits */
+ for (cnt = 0; cnt < 6; cnt++) {
+ dgt = bc(devc->buf[7 + cnt]);
+ if (dgt == 10) { /* Overload */
+ devc->value = NAN;
+ devc->scale = 1.0;
+ break;
+ }
+ else if (dgt == 13) { /* FUSE */
+ sr_err("FUSE!");
+ }
+ else if (dgt == 14) { /* Function recognition mode, OPEN */
+ sr_info("Function recognition mode, OPEN!");
+ devc->value = NAN;
+ devc->scale = 1.0;
+ break;
+ }
+ devc->value += pow(10.0, cnt) * dgt;
+ }
+ sr_spew("process_msg14() value=%f scale=%f scale1000=%d mq=%d "
+ "unit=%d mqflags=0x%02llx", devc->value, devc->scale,
+ devc->scale1000, devc->mq, devc->unit, devc->mqflags);
+ if (devc->value != NAN)
+ devc->value *= devc->scale * pow(1000.0, devc->scale1000);
+
+ send_value(sdi);
+
+ break;
+ default:
+ sr_spew("Unknown cmd %d!", devc->buf[3]);
+ break;
+ }
+
+ return SR_OK;
+}
+
+/** Data reception callback function. */