X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fvictor-dmm%2Fprotocol.c;fp=hardware%2Fvictor-dmm%2Fprotocol.c;h=0000000000000000000000000000000000000000;hb=155b680da482cea2381becb73c51cfb838bff31e;hp=6af51419326694c6241c349b850bb5c04a70a393;hpb=43cd4637285833706f8a404ca027bcf0ee75b9ae;p=libsigrok.git diff --git a/hardware/victor-dmm/protocol.c b/hardware/victor-dmm/protocol.c deleted file mode 100644 index 6af51419..00000000 --- a/hardware/victor-dmm/protocol.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * This file is part of the libsigrok project. - * - * Copyright (C) 2012 Bert Vermeulen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include "libsigrok.h" -#include "libsigrok-internal.h" -#include "protocol.h" - -/* Reverse the high nibble into the low nibble */ -static uint8_t decode_digit(uint8_t in) -{ - uint8_t out, i; - - out = 0; - in >>= 4; - for (i = 0x08; i; i >>= 1) { - out >>= 1; - if (in & i) - out |= 0x08; - } - - return out; -} - -static void decode_buf(struct sr_dev_inst *sdi, unsigned char *data) -{ - struct sr_datafeed_packet packet; - struct sr_datafeed_analog analog; - struct dev_context *devc; - long factor, ivalue; - uint8_t digits[4]; - gboolean is_duty, is_continuity, is_diode, is_ac, is_dc, is_auto; - gboolean is_hold, is_max, is_min, is_relative, minus; - float fvalue; - - devc = sdi->priv; - - digits[0] = decode_digit(data[12]); - digits[1] = decode_digit(data[11]); - digits[2] = decode_digit(data[10]); - digits[3] = decode_digit(data[9]); - - if (digits[0] == 0x0f && digits[1] == 0x00 && digits[2] == 0x0a && - digits[3] == 0x0f) - /* The "over limit" (OL) display comes through like this */ - ivalue = -1; - else if (digits[0] > 9 || digits[1] > 9 || digits[2] > 9 || digits[3] > 9) - /* An invalid digit in any position denotes no value. */ - ivalue = -2; - else { - ivalue = digits[0] * 1000; - ivalue += digits[1] * 100; - ivalue += digits[2] * 10; - ivalue += digits[3]; - } - - /* Decimal point position */ - factor = 0; - switch (data[7] >> 4) { - case 0x00: - factor = 0; - break; - case 0x02: - factor = 1; - break; - case 0x04: - factor = 2; - break; - case 0x08: - factor = 3; - break; - default: - sr_err("Unknown decimal point byte: 0x%.2x.", data[7]); - break; - } - - /* Minus flag */ - minus = data[2] & 0x01; - - /* Mode detail symbols on the right side of the digits */ - is_duty = is_continuity = is_diode = FALSE; - switch (data[4]) { - case 0x00: - /* None. */ - break; - case 0x01: - /* Micro */ - factor += 6; - break; - case 0x02: - /* Milli */ - factor += 3; - break; - case 0x04: - /* Kilo */ - ivalue *= 1000; - break; - case 0x08: - /* Mega */ - ivalue *= 1000000; - break; - case 0x10: - /* Continuity shows up as Ohm + this bit */ - is_continuity = TRUE; - break; - case 0x20: - /* Diode tester is Volt + this bit */ - is_diode = TRUE; - break; - case 0x40: - is_duty = TRUE; - break; - case 0x80: - /* Never seen */ - sr_dbg("Unknown mode right detail: 0x%.2x.", data[4]); - break; - default: - sr_dbg("Unknown/invalid mode right detail: 0x%.2x.", data[4]); - break; - } - - /* Scale flags on the right, continued */ - is_max = is_min = FALSE; - if (data[5] & 0x04) - is_max = TRUE; - if (data[5] & 0x08) - is_min = TRUE; - if (data[5] & 0x40) - /* Nano */ - factor += 9; - - /* Mode detail symbols on the left side of the digits */ - is_auto = is_dc = is_ac = is_hold = is_relative = FALSE; - if (data[6] & 0x04) - is_auto = TRUE; - if (data[6] & 0x08) - is_dc = TRUE; - if (data[6] & 0x10) - is_ac = TRUE; - if (data[6] & 0x20) - is_relative = TRUE; - if (data[6] & 0x40) - is_hold = TRUE; - - fvalue = (float)ivalue / pow(10, factor); - if (minus) - fvalue = -fvalue; - - memset(&analog, 0, sizeof(struct sr_datafeed_analog)); - - /* Measurement mode */ - analog.mq = -1; - switch (data[3]) { - case 0x00: - if (is_duty) { - analog.mq = SR_MQ_DUTY_CYCLE; - analog.unit = SR_UNIT_PERCENTAGE; - } else - sr_dbg("Unknown measurement mode: %.2x.", data[3]); - break; - case 0x01: - if (is_diode) { - analog.mq = SR_MQ_VOLTAGE; - analog.unit = SR_UNIT_VOLT; - analog.mqflags |= SR_MQFLAG_DIODE; - if (ivalue < 0) - fvalue = NAN; - } else { - if (ivalue < 0) - break; - analog.mq = SR_MQ_VOLTAGE; - analog.unit = SR_UNIT_VOLT; - if (is_ac) - analog.mqflags |= SR_MQFLAG_AC; - if (is_dc) - analog.mqflags |= SR_MQFLAG_DC; - } - break; - case 0x02: - analog.mq = SR_MQ_CURRENT; - analog.unit = SR_UNIT_AMPERE; - if (is_ac) - analog.mqflags |= SR_MQFLAG_AC; - if (is_dc) - analog.mqflags |= SR_MQFLAG_DC; - break; - case 0x04: - if (is_continuity) { - analog.mq = SR_MQ_CONTINUITY; - analog.unit = SR_UNIT_BOOLEAN; - fvalue = ivalue < 0 ? 0.0 : 1.0; - } else { - analog.mq = SR_MQ_RESISTANCE; - analog.unit = SR_UNIT_OHM; - if (ivalue < 0) - fvalue = INFINITY; - } - break; - case 0x08: - /* Never seen */ - sr_dbg("Unknown measurement mode: 0x%.2x.", data[3]); - break; - case 0x10: - analog.mq = SR_MQ_FREQUENCY; - analog.unit = SR_UNIT_HERTZ; - break; - case 0x20: - analog.mq = SR_MQ_CAPACITANCE; - analog.unit = SR_UNIT_FARAD; - break; - case 0x40: - analog.mq = SR_MQ_TEMPERATURE; - analog.unit = SR_UNIT_CELSIUS; - break; - case 0x80: - analog.mq = SR_MQ_TEMPERATURE; - analog.unit = SR_UNIT_FAHRENHEIT; - break; - default: - sr_dbg("Unknown/invalid measurement mode: 0x%.2x.", data[3]); - break; - } - if (analog.mq == -1) - return; - - if (is_auto) - analog.mqflags |= SR_MQFLAG_AUTORANGE; - if (is_hold) - analog.mqflags |= SR_MQFLAG_HOLD; - if (is_max) - analog.mqflags |= SR_MQFLAG_MAX; - if (is_min) - analog.mqflags |= SR_MQFLAG_MIN; - if (is_relative) - analog.mqflags |= SR_MQFLAG_RELATIVE; - - analog.channels = sdi->channels; - analog.num_samples = 1; - analog.data = &fvalue; - packet.type = SR_DF_ANALOG; - packet.payload = &analog; - sr_session_send(devc->cb_data, &packet); - - devc->num_samples++; -} - -SR_PRIV int victor_dmm_receive_data(struct sr_dev_inst *sdi, unsigned char *buf) -{ - GString *dbg; - int i; - unsigned char data[DMM_DATA_SIZE]; - unsigned char obfuscation[DMM_DATA_SIZE] = "jodenxunickxia"; - unsigned char shuffle[DMM_DATA_SIZE] = { - 6, 13, 5, 11, 2, 7, 9, 8, 3, 10, 12, 0, 4, 1 - }; - - for (i = 0; i < DMM_DATA_SIZE && buf[i] == 0; i++); - if (i == DMM_DATA_SIZE) { - /* This DMM outputs all zeroes from time to time, just ignore it. */ - sr_dbg("Received all zeroes."); - return SR_OK; - } - - /* Deobfuscate and reorder data. */ - for (i = 0; i < DMM_DATA_SIZE; i++) - data[shuffle[i]] = (buf[i] - obfuscation[i]) & 0xff; - - if (sr_log_loglevel_get() >= SR_LOG_SPEW) { - dbg = g_string_sized_new(128); - g_string_printf(dbg, "Deobfuscated."); - for (i = 0; i < DMM_DATA_SIZE; i++) - g_string_append_printf(dbg, " %.2x", data[i]); - sr_spew("%s", dbg->str); - g_string_free(dbg, TRUE); - } - - decode_buf(sdi, data); - - return SR_OK; -}