X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fbrymen-dmm%2Fparser.c;fp=hardware%2Fbrymen-dmm%2Fparser.c;h=0000000000000000000000000000000000000000;hb=155b680da482cea2381becb73c51cfb838bff31e;hp=e4b12274d41d862b3f08c6b85182545a300e39d5;hpb=43cd4637285833706f8a404ca027bcf0ee75b9ae;p=libsigrok.git diff --git a/hardware/brymen-dmm/parser.c b/hardware/brymen-dmm/parser.c deleted file mode 100644 index e4b12274..00000000 --- a/hardware/brymen-dmm/parser.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * This file is part of the libsigrok project. - * - * Copyright (C) 2012 Alexandru Gagniuc - * - * 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 "protocol.h" - -#define MAX_PACKET_LEN 22 - -/* Flags passed from the DMM. */ -struct brymen_flags { - gboolean is_low_batt, is_decibel, is_duty_cycle, is_hertz, is_amp; - gboolean is_beep, is_ohm, is_fahrenheit, is_celsius, is_capacitance; - gboolean is_diode, is_volt, is_dc, is_ac; -}; - -struct bm850_command { - uint8_t dle; - uint8_t stx; - uint8_t cmd; - uint8_t arg[2]; - uint8_t checksum; - uint8_t dle2; - uint8_t etx; -}; - -struct brymen_header { - uint8_t dle; - uint8_t stx; - uint8_t cmd; - uint8_t len; -}; - -struct brymen_tail { - uint8_t checksum; - uint8_t dle; - uint8_t etx; -}; - -/* - * We only have one command because we only support the BM-857. However, the - * driver is easily extensible to support more models, as the protocols are - * very similar. - */ -enum { - BM_CMD_REQUEST_READING = 0x00, -}; - -static int bm_send_command(uint8_t command, uint8_t arg1, uint8_t arg2, - struct sr_serial_dev_inst *serial) -{ - struct bm850_command cmdout; - int written; - - cmdout.dle = 0x10; - cmdout.stx = 0x02; - cmdout.cmd = command; - cmdout.arg[0] = arg1; - cmdout.arg[1] = arg2; - cmdout.checksum = arg1 ^ arg2; - cmdout.dle2 = 0x10; - cmdout.etx = 0x03; - - /* TODO: How to compute the checksum? Hardware seems to ignore it. */ - - /* Request reading. */ - written = serial_write(serial, &cmdout, sizeof(cmdout)); - if (written != sizeof(cmdout)) - return SR_ERR; - - return SR_OK; -} - -SR_PRIV int brymen_packet_request(struct sr_serial_dev_inst *serial) -{ - return bm_send_command(BM_CMD_REQUEST_READING, 0, 0, serial); -} - -SR_PRIV int brymen_packet_length(const uint8_t *buf, int *len) -{ - struct brymen_header *hdr; - int packet_len; - size_t buflen; - - buflen = *len; - hdr = (void *)buf; - - /* Did we receive a complete header yet? */ - if (buflen < sizeof(*hdr)) - return PACKET_NEED_MORE_DATA; - - if (hdr->dle != 0x10 || hdr->stx != 0x02) - return PACKET_INVALID_HEADER; - - /* Our packet includes the header, the payload, and the tail. */ - packet_len = sizeof(*hdr) + hdr->len + sizeof(struct brymen_tail); - - /* In case we pick up an invalid header, limit our search. */ - if (packet_len > MAX_PACKET_LEN) { - sr_spew("Header specifies an invalid payload length: %i.", - hdr->len); - return PACKET_INVALID_HEADER; - } - - *len = packet_len; - sr_spew("Expecting a %d-byte packet.", *len); - return PACKET_HEADER_OK; -} - -SR_PRIV gboolean brymen_packet_is_valid(const uint8_t *buf) -{ - struct brymen_header *hdr; - struct brymen_tail *tail; - int i; - uint8_t chksum = 0; - uint8_t *payload; - - payload = (uint8_t *)(buf + sizeof(struct brymen_header)); - - hdr = (void *)buf; - tail = (void *)(payload + hdr->len); - - for (i = 0; i< hdr->len; i++) - chksum ^= payload[i]; - - if (tail->checksum != chksum) { - sr_dbg("Packet has invalid checksum 0x%.2x. Expected 0x%.2x.", - chksum, tail->checksum); - return FALSE; - } - - return TRUE; -} - -static int parse_value(const char *strbuf, int len, float *floatval) -{ - int s, d; - char str[32]; - - if (strstr(strbuf, "OL")) { - sr_dbg("Overlimit."); - *floatval = INFINITY; - return SR_OK; - } - - memset(str, 0, sizeof(str)); - /* Spaces may interfere with parsing the exponent. Strip them. */ - for (s = 0, d = 0; s < len; s++) { - if (strbuf[s] != ' ') - str[d++] = strbuf[s]; - } - if (sr_atof_ascii(str, floatval) != SR_OK) - return SR_ERR; - - return SR_OK; -} - -static void parse_flags(const uint8_t *buf, struct brymen_flags *info) -{ - info->is_low_batt = (buf[4 + 3] & (1 << 7)) != 0; - - info->is_decibel = (buf[4 + 1] & (1 << 5)) != 0; - info->is_duty_cycle = (buf[4 + 1] & (1 << 3)) != 0; - info->is_hertz = (buf[4 + 1] & (1 << 2)) != 0; - info->is_amp = (buf[4 + 1] & (1 << 1)) != 0; - info->is_beep = (buf[4 + 1] & (1 << 0)) != 0; - - info->is_ohm = (buf[4 + 0] & (1 << 7)) != 0; - info->is_fahrenheit = (buf[4 + 0] & (1 << 6)) != 0; - info->is_celsius = (buf[4 + 0] & (1 << 5)) != 0; - info->is_diode = (buf[4 + 0] & (1 << 4)) != 0; - info->is_capacitance = (buf[4 + 0] & (1 << 3)) != 0; - info->is_volt = (buf[4 + 0] & (1 << 2)) != 0; - info->is_dc = (buf[4 + 0] & (1 << 1)) != 0; - info->is_ac = (buf[4 + 0] & (1 << 0)) != 0; -} - -SR_PRIV int brymen_parse(const uint8_t *buf, float *floatval, - struct sr_datafeed_analog *analog, void *info) -{ - struct brymen_flags flags; - struct brymen_header *hdr; - uint8_t *bfunc; - int asciilen; - - (void)info; - - hdr = (void *)buf; - bfunc = (uint8_t *)(buf + sizeof(struct brymen_header)); - - analog->mqflags = 0; - - /* Give some debug info about the package. */ - asciilen = hdr->len - 4; - sr_dbg("DMM flags: %.2x %.2x %.2x %.2x", - bfunc[3], bfunc[2], bfunc[1], bfunc[0]); - /* Value is an ASCII string. */ - sr_dbg("DMM packet: \"%.*s\"", asciilen, bfunc + 4); - - parse_flags(buf, &flags); - if (parse_value((const char *)(bfunc + 4), asciilen, floatval) != SR_OK) - return SR_ERR; - - if (flags.is_volt) { - analog->mq = SR_MQ_VOLTAGE; - analog->unit = SR_UNIT_VOLT; - } - if (flags.is_amp) { - analog->mq = SR_MQ_CURRENT; - analog->unit = SR_UNIT_AMPERE; - } - if (flags.is_ohm) { - if (flags.is_beep) - analog->mq = SR_MQ_CONTINUITY; - else - analog->mq = SR_MQ_RESISTANCE; - analog->unit = SR_UNIT_OHM; - } - if (flags.is_hertz) { - analog->mq = SR_MQ_FREQUENCY; - analog->unit = SR_UNIT_HERTZ; - } - if (flags.is_duty_cycle) { - analog->mq = SR_MQ_DUTY_CYCLE; - analog->unit = SR_UNIT_PERCENTAGE; - } - if (flags.is_capacitance) { - analog->mq = SR_MQ_CAPACITANCE; - analog->unit = SR_UNIT_FARAD; - } - if (flags.is_fahrenheit) { - analog->mq = SR_MQ_TEMPERATURE; - analog->unit = SR_UNIT_FAHRENHEIT; - } - if (flags.is_celsius) { - analog->mq = SR_MQ_TEMPERATURE; - analog->unit = SR_UNIT_CELSIUS; - } - if (flags.is_capacitance) { - analog->mq = SR_MQ_CAPACITANCE; - analog->unit = SR_UNIT_FARAD; - } - - /* - * The high-end Brymen models have a configurable reference impedance. - * When the reference impedance is changed, the DMM sends one packet - * with the value of the new reference impedance. Both decibel and ohm - * flags are set in this case, so we must be careful to correctly - * identify the value as ohm, not dBmW. - */ - if (flags.is_decibel && !flags.is_ohm) { - analog->mq = SR_MQ_POWER; - analog->unit = SR_UNIT_DECIBEL_MW; - /* - * For some reason, dBm measurements are sent by the multimeter - * with a value three orders of magnitude smaller than the - * displayed value. - */ - *floatval *= 1000; - } - - if (flags.is_diode) - analog->mqflags |= SR_MQFLAG_DIODE; - /* We can have both AC+DC in a single measurement. */ - if (flags.is_ac) - analog->mqflags |= SR_MQFLAG_AC; - if (flags.is_dc) - analog->mqflags |= SR_MQFLAG_DC; - - if (flags.is_low_batt) - sr_info("Low battery!"); - - return SR_OK; -}