From 9a1a7dc2832b0c51baff94ef551518d91f47ff31 Mon Sep 17 00:00:00 2001 From: Gerhard Sittig Date: Thu, 24 Sep 2020 21:50:37 +0200 Subject: [PATCH] brymen-dmm: remove obsolete driver (support has moved to serial-dmm) The DMM support for Brymen BM850s has moved to src/dmm/ and became part of the serial-dmm driver. Remove the now obsolete brymen-dmm/ source code. --- Makefile.am | 7 - README.devices | 1 - configure.ac | 1 - src/hardware/brymen-dmm/api.c | 192 ---------------- src/hardware/brymen-dmm/parser.c | 352 ----------------------------- src/hardware/brymen-dmm/protocol.c | 256 --------------------- src/hardware/brymen-dmm/protocol.h | 73 ------ 7 files changed, 882 deletions(-) delete mode 100644 src/hardware/brymen-dmm/api.c delete mode 100644 src/hardware/brymen-dmm/parser.c delete mode 100644 src/hardware/brymen-dmm/protocol.c delete mode 100644 src/hardware/brymen-dmm/protocol.h diff --git a/Makefile.am b/Makefile.am index 9110cfe0..71d560d2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -260,13 +260,6 @@ src_libdrivers_la_SOURCES += \ src/hardware/beaglelogic/beaglelogic_native.c \ src/hardware/beaglelogic/beaglelogic_tcp.c endif -if HW_BRYMEN_DMM -src_libdrivers_la_SOURCES += \ - src/hardware/brymen-dmm/parser.c \ - src/hardware/brymen-dmm/protocol.h \ - src/hardware/brymen-dmm/protocol.c \ - src/hardware/brymen-dmm/api.c -endif if HW_CEM_DT_885X src_libdrivers_la_SOURCES += \ src/hardware/cem-dt-885x/protocol.h \ diff --git a/README.devices b/README.devices index 97aca278..fc0e6405 100644 --- a/README.devices +++ b/README.devices @@ -98,7 +98,6 @@ The following drivers/devices do not need any firmware upload: - atten-pps3xxx - baylibre-acme - beaglelogic - - brymen-dmm - cem-dt-885x - center-3xx (including all subdrivers) - chronovu-la diff --git a/configure.ac b/configure.ac index 2f8c2c36..26621fd9 100644 --- a/configure.ac +++ b/configure.ac @@ -264,7 +264,6 @@ SR_DRIVER([ASIX SIGMA/SIGMA2], [asix-sigma], [libftdi]) SR_DRIVER([Atten PPS3xxx], [atten-pps3xxx], [serial_comm]) SR_DRIVER([BayLibre ACME], [baylibre-acme], [sys_timerfd_h]) SR_DRIVER([BeagleLogic], [beaglelogic], [sys_mman_h sys_ioctl_h]) -SR_DRIVER([Brymen DMM], [brymen-dmm], [serial_comm]) SR_DRIVER([CEM DT-885x], [cem-dt-885x], [serial_comm]) SR_DRIVER([Center 3xx], [center-3xx], [serial_comm]) SR_DRIVER([ChronoVu LA], [chronovu-la], [libusb libftdi]) diff --git a/src/hardware/brymen-dmm/api.c b/src/hardware/brymen-dmm/api.c deleted file mode 100644 index dacbee88..00000000 --- a/src/hardware/brymen-dmm/api.c +++ /dev/null @@ -1,192 +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 -#include "protocol.h" - -static const uint32_t scanopts[] = { - SR_CONF_CONN, - SR_CONF_SERIALCOMM, -}; - -static const uint32_t drvopts[] = { - SR_CONF_MULTIMETER, -}; - -static const uint32_t devopts[] = { - SR_CONF_CONTINUOUS, - SR_CONF_LIMIT_SAMPLES | SR_CONF_SET, - SR_CONF_LIMIT_MSEC | SR_CONF_SET, -}; - -static GSList *brymen_scan(struct sr_dev_driver *di, const char *conn, - const char *serialcomm) -{ - struct sr_dev_inst *sdi; - struct dev_context *devc; - struct sr_serial_dev_inst *serial; - int rts_toggle_delay_us; - GSList *devices; - int ret; - uint8_t buf[128]; - size_t len; - - serial = sr_serial_dev_inst_new(conn, serialcomm); - - if (serial_open(serial, SERIAL_RDWR) != SR_OK) - return NULL; - /* - * The device requires an RTS *pulse* before communication. - * The vendor's documentation recommends the following sequence: - * Open the COM port, wait for 100ms, set RTS=1, wait for 100ms, - * set RTS=0, wait for 100ms, set RTS=1, configure bitrate and - * frame format, transmit request data, receive response data. - */ - rts_toggle_delay_us = 100 * 1000; /* 100ms */ - g_usleep(rts_toggle_delay_us); - serial_set_handshake(serial, 1, -1); - g_usleep(rts_toggle_delay_us); - serial_set_handshake(serial, 0, -1); - g_usleep(rts_toggle_delay_us); - serial_set_handshake(serial, 1, -1); - g_usleep(rts_toggle_delay_us); - - sr_info("Probing port %s.", conn); - - devices = NULL; - - /* Request reading */ - if ((ret = brymen_packet_request(serial)) < 0) { - sr_err("Unable to send command: %d.", ret); - goto scan_cleanup; - } - - len = sizeof(buf); - ret = brymen_stream_detect(serial, buf, &len, brymen_packet_length, - brymen_packet_is_valid, 1000, 9600); - if (ret != SR_OK) - goto scan_cleanup; - - sr_info("Found device on port %s.", conn); - - sdi = g_malloc0(sizeof(struct sr_dev_inst)); - sdi->status = SR_ST_INACTIVE; - sdi->vendor = g_strdup("Brymen"); - sdi->model = g_strdup("BM85x"); - devc = g_malloc0(sizeof(struct dev_context)); - sr_sw_limits_init(&devc->sw_limits); - sdi->inst_type = SR_INST_SERIAL; - sdi->conn = serial; - sdi->priv = devc; - sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1"); - devices = g_slist_append(devices, sdi); - -scan_cleanup: - serial_close(serial); - - return std_scan_complete(di, devices); -} - -static GSList *scan(struct sr_dev_driver *di, GSList *options) -{ - struct sr_config *src; - GSList *devices, *l; - const char *conn, *serialcomm; - - devices = NULL; - - /* - * BEWARE! Default 'conn' is not desirable when the device cannot - * reliably get detected. Insist that users specify the port. - */ - conn = NULL; - serialcomm = "9600/8n1/dtr=1/rts=1"; - for (l = options; l; l = l->next) { - src = l->data; - switch (src->key) { - case SR_CONF_CONN: - conn = g_variant_get_string(src->data, NULL); - break; - case SR_CONF_SERIALCOMM: - serialcomm = g_variant_get_string(src->data, NULL); - break; - } - } - if (!conn) - return NULL; - - devices = brymen_scan(di, conn, serialcomm); - - return devices; -} - -static int config_set(uint32_t key, GVariant *data, - const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) -{ - struct dev_context *devc; - - (void)cg; - - devc = sdi->priv; - - return sr_sw_limits_config_set(&devc->sw_limits, key, data); -} - -static int config_list(uint32_t key, GVariant **data, - const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) -{ - return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts); -} - -static int dev_acquisition_start(const struct sr_dev_inst *sdi) -{ - struct dev_context *devc; - struct sr_serial_dev_inst *serial; - - devc = sdi->priv; - - sr_sw_limits_acquisition_start(&devc->sw_limits); - std_session_send_df_header(sdi); - - serial = sdi->conn; - serial_source_add(sdi->session, serial, G_IO_IN, 50, - brymen_dmm_receive_data, (void *)sdi); - - return SR_OK; -} - -static struct sr_dev_driver brymen_bm857_driver_info = { - .name = "brymen-bm857", - .longname = "Brymen BM857", - .api_version = 1, - .init = std_init, - .cleanup = std_cleanup, - .scan = scan, - .dev_list = std_dev_list, - .dev_clear = std_dev_clear, - .config_get = NULL, - .config_set = config_set, - .config_list = config_list, - .dev_open = std_serial_dev_open, - .dev_close = std_serial_dev_close, - .dev_acquisition_start = dev_acquisition_start, - .dev_acquisition_stop = std_serial_dev_acquisition_stop, - .context = NULL, -}; -SR_REGISTER_DEV_DRIVER(brymen_bm857_driver_info); diff --git a/src/hardware/brymen-dmm/parser.c b/src/hardware/brymen-dmm/parser.c deleted file mode 100644 index cc0a05c6..00000000 --- a/src/hardware/brymen-dmm/parser.c +++ /dev/null @@ -1,352 +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 -#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_blocking(serial, &cmdout, sizeof(cmdout), - serial_timeout(serial, 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 *txt, size_t len, float *floatval) -{ - const char *txt_end; - char c, buf[32], *dst; - int ret; - - /* - * The input text is not NUL terminated, the checksum follows - * the value text field. Spaces may interfere with the text to - * number conversion, especially with exponent parsing. Copy the - * input data to a terminated text buffer and strip spaces in the - * process, before running ASCIIZ string operations. - */ - if (len >= sizeof(buf)) { - sr_err("Insufficient text conversion buffer size."); - return SR_ERR_BUG; - } - txt_end = txt + len; - dst = &buf[0]; - while (txt < txt_end && *txt) { - c = *txt++; - if (c == ' ') - continue; - *dst++ = c; - } - *dst = '\0'; - - /* Check for overflow, or get the number value. */ - if (strstr(buf, "+OL")) { - *floatval = +INFINITY; - return SR_OK; - } - if (strstr(buf, "-OL")) { - *floatval = -INFINITY; - return SR_OK; - } - if (strstr(buf, "OL")) { - *floatval = INFINITY; - return SR_OK; - } - ret = sr_atof_ascii(buf, floatval); - if (ret != SR_OK) - return ret; - - return SR_OK; -} - -static void parse_flags(const uint8_t *bfunc, struct brymen_flags *info) -{ - info->is_low_batt = (bfunc[3] & (1 << 7)) != 0; - - info->is_decibel = (bfunc[1] & (1 << 5)) != 0; - info->is_duty_cycle = (bfunc[1] & (1 << 3)) != 0; - info->is_hertz = (bfunc[1] & (1 << 2)) != 0; - info->is_amp = (bfunc[1] & (1 << 1)) != 0; - info->is_beep = (bfunc[1] & (1 << 0)) != 0; - - info->is_ohm = (bfunc[0] & (1 << 7)) != 0; - info->is_fahrenheit = (bfunc[0] & (1 << 6)) != 0; - info->is_celsius = (bfunc[0] & (1 << 5)) != 0; - info->is_diode = (bfunc[0] & (1 << 4)) != 0; - info->is_capacitance = (bfunc[0] & (1 << 3)) != 0; - info->is_volt = (bfunc[0] & (1 << 2)) != 0; - info->is_dc = (bfunc[0] & (1 << 1)) != 0; - info->is_ac = (bfunc[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; - const char *txt; - int txtlen; - char *p; - char *unit; - int ret; - - (void)info; - - hdr = (void *)buf; - bfunc = (uint8_t *)(buf + sizeof(struct brymen_header)); - txt = (const char *)&bfunc[4]; - txtlen = hdr->len - 4; - sr_dbg("DMM bfunc: %02x %02x %02x %02x, text '%.*s'", - bfunc[3], bfunc[2], bfunc[1], bfunc[0], txtlen, txt); - - memset(&flags, 0, sizeof(flags)); - parse_flags(bfunc, &flags); - if (flags.is_decibel && flags.is_ohm) { - /* - * The reference impedance for the dBm function is in an - * unexpected format. Naive conversion of non-space chars - * gives incorrect results. Isolate the 4..1200 Ohms value - * instead, ignore the "0." and exponent parts of the - * response text. - */ - if (strncmp(txt, " 0.", strlen(" 0.")) == 0 && strstr(txt, " E")) { - txt = &txt[strlen(" 0.")]; - txtlen -= strlen(" 0."); - p = strchr(txt, 'E'); - if (p) - *p = '\0'; - } - } - if (flags.is_fahrenheit || flags.is_celsius) { - /* - * The value text in temperature mode includes the C/F - * suffix between the mantissa and the exponent, which - * breaks the text to number conversion. Example data: - * " 0.0217CE+3". Remove the C/F unit identifier. - */ - unit = strchr(txt, flags.is_fahrenheit ? 'F' : 'C'); - if (!unit) - return SR_ERR; - *unit = ' '; - } - ret = parse_value(txt, txtlen, floatval); - sr_dbg("floatval: %f, ret %d", *floatval, ret); - if (ret != SR_OK) - return SR_ERR; - - analog->meaning->mqflags = 0; - if (flags.is_volt) { - analog->meaning->mq = SR_MQ_VOLTAGE; - analog->meaning->unit = SR_UNIT_VOLT; - } - if (flags.is_amp) { - analog->meaning->mq = SR_MQ_CURRENT; - analog->meaning->unit = SR_UNIT_AMPERE; - } - if (flags.is_ohm) { - if (flags.is_decibel) - analog->meaning->mq = SR_MQ_RESISTANCE; - else if (flags.is_beep) - analog->meaning->mq = SR_MQ_CONTINUITY; - else - analog->meaning->mq = SR_MQ_RESISTANCE; - analog->meaning->unit = SR_UNIT_OHM; - } - if (flags.is_hertz) { - analog->meaning->mq = SR_MQ_FREQUENCY; - analog->meaning->unit = SR_UNIT_HERTZ; - } - if (flags.is_duty_cycle) { - analog->meaning->mq = SR_MQ_DUTY_CYCLE; - analog->meaning->unit = SR_UNIT_PERCENTAGE; - } - if (flags.is_capacitance) { - analog->meaning->mq = SR_MQ_CAPACITANCE; - analog->meaning->unit = SR_UNIT_FARAD; - } - if (flags.is_fahrenheit) { - analog->meaning->mq = SR_MQ_TEMPERATURE; - analog->meaning->unit = SR_UNIT_FAHRENHEIT; - } - if (flags.is_celsius) { - analog->meaning->mq = SR_MQ_TEMPERATURE; - analog->meaning->unit = SR_UNIT_CELSIUS; - } - if (flags.is_capacitance) { - analog->meaning->mq = SR_MQ_CAPACITANCE; - analog->meaning->unit = SR_UNIT_FARAD; - } - - /* - * The high-end Brymen models have a configurable reference - * impedance for dBm measurements. When the meter's function - * is entered, or when the reference impedance is changed, the - * meter sends one packet with the value of the new reference. - * Both decibel and ohm flags are set in this case, so we must - * be careful to not clobber the resistance value from above, - * and only provide dBm when the measurement is shown and not - * its reference. - * - * The meter's response values also use an unexpected scale - * (always off by factor 1000, as if it was Watts not mW). - * - * Example responses: - * bfunc: 00 00 20 80, text ' 0. 800 E+1' (reference) - * bfunc: 00 00 20 00, text '-0.3702 E-1' (measurement) - */ - if (flags.is_decibel && !flags.is_ohm) { - analog->meaning->mq = SR_MQ_POWER; - analog->meaning->unit = SR_UNIT_DECIBEL_MW; - *floatval *= 1000; - } - - if (flags.is_diode) - analog->meaning->mqflags |= SR_MQFLAG_DIODE | SR_MQFLAG_DC; - /* We can have both AC+DC in a single measurement. */ - if (flags.is_ac) - analog->meaning->mqflags |= SR_MQFLAG_AC; - if (flags.is_dc) - analog->meaning->mqflags |= SR_MQFLAG_DC; - - if (flags.is_low_batt) - sr_warn("Low battery!"); - - return SR_OK; -} diff --git a/src/hardware/brymen-dmm/protocol.c b/src/hardware/brymen-dmm/protocol.c deleted file mode 100644 index 3dd8dd31..00000000 --- a/src/hardware/brymen-dmm/protocol.c +++ /dev/null @@ -1,256 +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 -#include "protocol.h" - -static void handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi) -{ - float floatval; - struct dev_context *devc; - struct sr_datafeed_packet packet; - struct sr_datafeed_analog analog; - struct sr_analog_encoding encoding; - struct sr_analog_meaning meaning; - struct sr_analog_spec spec; - - devc = sdi->priv; - - /* TODO: Use proper 'digits' value for this device (and its modes). */ - sr_analog_init(&analog, &encoding, &meaning, &spec, 2); - - analog.num_samples = 1; - analog.meaning->mq = 0; - - if (brymen_parse(buf, &floatval, &analog, NULL) != SR_OK) - return; - analog.data = &floatval; - - analog.meaning->channels = sdi->channels; - - if (analog.meaning->mq != 0) { - /* Got a measurement. */ - packet.type = SR_DF_ANALOG; - packet.payload = &analog; - sr_session_send(sdi, &packet); - sr_sw_limits_update_samples_read(&devc->sw_limits, 1); - } -} - -static void handle_new_data(struct sr_dev_inst *sdi) -{ - struct dev_context *devc; - int len, status, offset = 0; - struct sr_serial_dev_inst *serial; - - devc = sdi->priv; - serial = sdi->conn; - - /* Try to get as much data as the buffer can hold. */ - len = DMM_BUFSIZE - devc->buflen; - len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len); - if (len < 1) { - sr_err("Serial port read error: %d.", len); - return; - } - devc->buflen += len; - status = PACKET_INVALID_HEADER; - - /* Now look for packets in that data. */ - while (status != PACKET_NEED_MORE_DATA) { - /* We don't have a header, look for one. */ - if (devc->next_packet_len == 0) { - len = devc->buflen - offset; - status = brymen_packet_length(devc->buf + offset, &len); - if (status == PACKET_HEADER_OK) { - /* We know how large the packet will be. */ - devc->next_packet_len = len; - } else if (status == PACKET_NEED_MORE_DATA) { - /* We didn't yet receive the full header. */ - devc->next_packet_len = 0; - break; - } else { - /* Invalid header. Move on. */ - devc->next_packet_len = 0; - offset++; - continue; - } - } - - /* We know how the packet size, but did we receive all of it? */ - if (devc->buflen - offset < devc->next_packet_len) - break; - - /* We should have a full packet here, so we can check it. */ - if (brymen_packet_is_valid(devc->buf + offset)) { - handle_packet(devc->buf + offset, sdi); - offset += devc->next_packet_len; - } else { - offset++; - } - - /* We are done with this packet. Look for a new one. */ - devc->next_packet_len = 0; - } - - /* If we have any data left, move it to the beginning of our buffer. */ - memmove(devc->buf, devc->buf + offset, devc->buflen - offset); - devc->buflen -= offset; -} - -SR_PRIV int brymen_dmm_receive_data(int fd, int revents, void *cb_data) -{ - struct sr_dev_inst *sdi; - struct dev_context *devc; - struct sr_serial_dev_inst *serial; - int ret; - - (void)fd; - - if (!(sdi = cb_data)) - return TRUE; - - if (!(devc = sdi->priv)) - return TRUE; - - serial = sdi->conn; - - if (revents == G_IO_IN) { - /* Serial data arrived. */ - handle_new_data(sdi); - } else { - /* Timeout, send another packet request. */ - if ((ret = brymen_packet_request(serial)) < 0) { - sr_err("Failed to request packet: %d.", ret); - return FALSE; - } - } - - if (sr_sw_limits_check(&devc->sw_limits)) - sr_dev_acquisition_stop(sdi); - - return TRUE; -} - -/** - * Try to find a valid packet in a serial data stream. - * - * @param serial Previously initialized serial port structure. - * @param buf Buffer containing the bytes to write. - * @param buflen Size of the buffer. - * @param get_packet_size Callback that assesses the size of incoming packets. - * @param is_valid Callback that assesses whether the packet is valid or not. - * @param timeout_ms The timeout after which, if no packet is detected, to - * abort scanning. - * @param baudrate The baudrate of the serial port. This parameter is not - * critical, but it helps fine tune the serial port polling - * delay. - * - * @return SR_OK if a valid packet is found within the given timeout, - * SR_ERR upon failure. - */ -SR_PRIV int brymen_stream_detect(struct sr_serial_dev_inst *serial, - uint8_t *buf, size_t *buflen, - packet_length_t get_packet_size, - packet_valid_callback is_valid, - uint64_t timeout_ms, int baudrate) -{ - int64_t start, time, byte_delay_us; - size_t ibuf, i, maxlen; - ssize_t len, stream_len; - int packet_len; - int status; - - maxlen = *buflen; - - sr_dbg("Detecting packets on %s (timeout = %" PRIu64 - "ms, baudrate = %d).", serial->port, timeout_ms, baudrate); - - /* Assume 8n1 transmission. That is 10 bits for every byte. */ - byte_delay_us = 10 * ((1000 * 1000) / baudrate); - start = g_get_monotonic_time(); - - packet_len = i = ibuf = len = 0; - while (ibuf < maxlen) { - len = serial_read_nonblocking(serial, &buf[ibuf], maxlen - ibuf); - if (len > 0) { - ibuf += len; - sr_spew("Read %zd bytes.", len); - } - - time = g_get_monotonic_time() - start; - time /= 1000; - - stream_len = ibuf - i; - if (stream_len > 0 && packet_len == 0) { - /* How large of a packet are we expecting? */ - packet_len = stream_len; - status = get_packet_size(&buf[i], &packet_len); - switch (status) { - case PACKET_HEADER_OK: - /* We know how much data we need to wait for. */ - break; - case PACKET_NEED_MORE_DATA: - /* We did not receive the full header. */ - packet_len = 0; - break; - case PACKET_INVALID_HEADER: - default: - /* - * We had enough data, but here was an error in - * parsing the header. Restart parsing from the - * next byte. - */ - packet_len = 0; - i++; - break; - } - } - - if ((stream_len >= packet_len) && (packet_len != 0)) { - /* We have at least a packet's worth of data. */ - if (is_valid(&buf[i])) { - sr_spew("Found valid %d-byte packet after " - "%" PRIu64 "ms.", packet_len, time); - *buflen = ibuf; - return SR_OK; - } else { - sr_spew("Got %d bytes, but not a valid " - "packet.", packet_len); - - } - - /* Not a valid packet. Continue searching. */ - i++; - packet_len = 0; - } - - if (time >= (int64_t)timeout_ms) { - /* Timeout */ - sr_dbg("Detection timed out after %" PRIi64 "ms.", time); - break; - } - g_usleep(byte_delay_us); - } - - *buflen = ibuf; - sr_err("Didn't find a valid packet (read %zu bytes).", ibuf); - - return SR_ERR; -} diff --git a/src/hardware/brymen-dmm/protocol.h b/src/hardware/brymen-dmm/protocol.h deleted file mode 100644 index ec839d48..00000000 --- a/src/hardware/brymen-dmm/protocol.h +++ /dev/null @@ -1,73 +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 . - */ - -#ifndef LIBSIGROK_HARDWARE_BRYMEN_DMM_PROTOCOL_H -#define LIBSIGROK_HARDWARE_BRYMEN_DMM_PROTOCOL_H - -#include -#include -#include -#include -#include -#include -#include "libsigrok-internal.h" - -#define LOG_PREFIX "brymen-dmm" - -#define DMM_BUFSIZE 256 - -enum packet_len_status { - PACKET_HEADER_OK, - PACKET_NEED_MORE_DATA, - PACKET_INVALID_HEADER, -}; - -struct dev_context { - struct sr_sw_limits sw_limits; - uint8_t buf[DMM_BUFSIZE]; - int bufoffset; - int buflen; - int next_packet_len; -}; - -/** - * Callback that assesses the size and status of the incoming packet. - * - * @return PACKET_HEADER_OK - This is a proper packet header. - * PACKET_NEED_MORE_DATA The buffer does not contain the entire header. - * PACKET_INVALID_HEADER Not a valid start of packet. - */ -typedef int (*packet_length_t)(const uint8_t *buf, int *len); - -SR_PRIV int brymen_dmm_receive_data(int fd, int revents, void *cb_data); -SR_PRIV int brymen_packet_request(struct sr_serial_dev_inst *serial); - -SR_PRIV int brymen_packet_length(const uint8_t *buf, int *len); -SR_PRIV gboolean brymen_packet_is_valid(const uint8_t *buf); - -SR_PRIV int brymen_parse(const uint8_t *buf, float *floatval, - struct sr_datafeed_analog *analog, void *info); - -SR_PRIV int brymen_stream_detect(struct sr_serial_dev_inst *serial, - uint8_t *buf, size_t *buflen, - packet_length_t get_packet_size, - packet_valid_callback is_valid, - uint64_t timeout_ms, int baudrate); - -#endif -- 2.30.2