Skip to content

Commit

Permalink
Merge branch 'sigrokproject:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
fredzo authored Aug 26, 2024
2 parents e2f494b + 0dfa850 commit ddb3dcf
Show file tree
Hide file tree
Showing 19 changed files with 440 additions and 21 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ endif
# Hardware (DMM chip parsers)
libsigrok_la_SOURCES += \
src/dmm/asycii.c \
src/dmm/qm1578.c \
src/dmm/bm25x.c \
src/dmm/bm52x.c \
src/dmm/bm85x.c \
Expand Down
2 changes: 2 additions & 0 deletions bindings/swig/classes.i
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ typedef std::map<const sigrok::ConfigKey *, Glib::VariantBase>
%attributestring(sigrok::Device, std::string, vendor, vendor);
%attributestring(sigrok::Device, std::string, model, model);
%attributestring(sigrok::Device, std::string, version, version);
%attributestring(sigrok::Device, std::string, serial_number, serial_number);
%attributestring(sigrok::Device, std::string, connection_id, connection_id);

%attributevector(Device,
std::vector<std::shared_ptr<sigrok::Channel> >,
Expand Down
7 changes: 7 additions & 0 deletions contrib/60-libsigrok.rules
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@ ATTRS{idVendor}=="0aad", ATTRS{idProduct}=="0119", ENV{ID_SIGROK}="1"
# Rohde&Schwarz HMC series power supply (previously branded Hameg) VCP/USBTMC mode
ATTRS{idVendor}=="0aad", ATTRS{idProduct}=="0135", ENV{ID_SIGROK}="1"

# Rohde&Schwarz NGE100B series power supply VCP/USBTMC mode
ATTRS{idVendor}=="0aad", ATTRS{idProduct}=="0197", ENV{ID_SIGROK}="1"

# Sainsmart DDS120 / Rocktech BM102, renumerates as 1d50:608e "sigrok fx2lafw", Serial: Sainsmart DDS120
ATTRS{idVendor}=="8102", ATTRS{idProduct}=="8102", ENV{ID_SIGROK}="1"

Expand Down Expand Up @@ -368,6 +371,8 @@ ATTRS{idVendor}=="d4a2", ATTRS{idProduct}=="5660", ENV{ID_SIGROK}="1"
# 0c12:700e: LAP-C(16032)
# 0c12:7016: LAP-C(162000)
# 0c12:7025: LAP-C(16128+)
# 0c12:7060: Logian-16L
# 0c12:7064: Logian-16L
# 0c12:7100: AKIP-9101
ATTRS{idVendor}=="0c12", ATTRS{idProduct}=="7002", ENV{ID_SIGROK}="1"
ATTRS{idVendor}=="0c12", ATTRS{idProduct}=="7007", ENV{ID_SIGROK}="1"
Expand All @@ -379,6 +384,8 @@ ATTRS{idVendor}=="0c12", ATTRS{idProduct}=="700d", ENV{ID_SIGROK}="1"
ATTRS{idVendor}=="0c12", ATTRS{idProduct}=="700e", ENV{ID_SIGROK}="1"
ATTRS{idVendor}=="0c12", ATTRS{idProduct}=="7016", ENV{ID_SIGROK}="1"
ATTRS{idVendor}=="0c12", ATTRS{idProduct}=="7025", ENV{ID_SIGROK}="1"
ATTRS{idVendor}=="0c12", ATTRS{idProduct}=="7060", ENV{ID_SIGROK}="1"
ATTRS{idVendor}=="0c12", ATTRS{idProduct}=="7064", ENV{ID_SIGROK}="1"
ATTRS{idVendor}=="0c12", ATTRS{idProduct}=="7100", ENV{ID_SIGROK}="1"

LABEL="libsigrok_rules_end"
14 changes: 14 additions & 0 deletions include/libsigrok/libsigrok.h
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,11 @@ enum sr_configkey {
*/
SR_CONF_MULTIPLEXER,

/**
* The device can act as a digital delay generator.
*/
SR_CONF_DELAY_GENERATOR,

/* Update sr_key_info_config[] (hwdriver.c) upon changes! */

/*--- Driver scan options -------------------------------------------*/
Expand Down Expand Up @@ -1137,6 +1142,15 @@ enum sr_configkey {
*/
SR_CONF_OVER_CURRENT_PROTECTION_DELAY,

/**
* Signal inversion.
* @arg type: boolean
* @arg get: @b true if the signal is inverted or has negative polarity,
* @b false otherwise
* @arg set: set @b true to invert the signal
*/
SR_CONF_INVERTED,

/* Update sr_key_info_config[] (hwdriver.c) upon changes! */

/*--- Special stuff -------------------------------------------------*/
Expand Down
2 changes: 2 additions & 0 deletions src/backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,11 @@ SR_API GSList *sr_buildinfo_libs_get(void)
glib_binary_age, glib_interface_age));
l = g_slist_append(l, m);

#ifdef HAVE_ZLIB
m = g_slist_append(NULL, g_strdup("zlib"));
m = g_slist_append(m, g_strdup_printf("%s", CONF_ZLIB_VERSION));
l = g_slist_append(l, m);
#endif

m = g_slist_append(NULL, g_strdup("libzip"));
m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBZIP_VERSION));
Expand Down
210 changes: 210 additions & 0 deletions src/dmm/qm1578.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* This file is part of the libsigrok project.
*
* Copyright (C) 2014 Janne Huttunen <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

/**
* @file
*
* qm1578.c
*
* Digitech QM1576 serial protocol parser for libsigrok.
* QM1576 is a 600 count RMS DMM, with Bluetooth 4.0 support.
* https://www.jaycar.com.au/true-rms-digital-multimeter-with-bluetooth-connectivity/p/QM1578
*
* The protocol is described at https://www.airspayce.com/mikem/QM1578/protocol.txt
*
* You can use this decoder with libsigrok and Digitech QM1578 via ESP32 Bluetooth-Serial converter
* available from the author at:
* https://www.airspayce.com/mikem/QM1578/QM1578BluetoothClient.ino
* which connects to the QM1578 over Bluetooth LE, fetches the
* data stream and sends it on the serial port to the host, where this driver can read it
* with this command for example:
* sigrok-cli --driver digitech-qm1578:conn=/dev/ttyUSB1 --continuous
*
* See https://www.airspayce.com/mikem/QM1578//README for more data
*
* Author: [email protected]
*/

#include <config.h>
#include <math.h>
#include <libsigrok/libsigrok.h>
#include "libsigrok-internal.h"

#define LOG_PREFIX "digitech-qm1578"

/* Number of digits the meter supports */
#define MAX_DIGITS 4

/* Decode the multiplier prefix from buf[11] */
static int decode_prefix(const uint8_t *buf)
{
switch (buf[11]) {
case 0x00: return 0;
case 0x01: return 3;
case 0x02: return 6;
case 0x03: return -9;
case 0x04: return -6;
case 0x05: return -3; /* For amps */
case 0x06: return -3; /* For volts */
default:
sr_dbg("Unknown multiplier: 0x%02x.", buf[11]);
return -1;
}
}

static float decode_value(const uint8_t *buf, int *exponent)
{
float val = 0.0f;
int i, digit;

/* On overload, digits 4 to 1 are: 0x0b 0x0a 0x00 0x0b */
if (buf[8] == 0x0b)
return INFINITY;

/* Decode the 4 digits */
for (i = 0; i < MAX_DIGITS; i++) {
digit = buf[8 - i];
if (digit < 0 || digit > 9)
continue;
val = 10.0 * val + digit;
}

*exponent = -buf[9];
return val;
}

SR_PRIV gboolean sr_digitech_qm1578_packet_valid(const uint8_t *buf)
{
/*
* First 4 digits on my meter are always 0d5 0xf0 0x00 0x0a
* Dont know if thats the same for all meters or just mine, so ignore them
* and just use the presence of the trailing record separator
*/
if (buf[14] != 0x0d)
return FALSE;

return TRUE;
}

SR_PRIV int sr_digitech_qm1578_parse(const uint8_t *buf, float *floatval,
struct sr_datafeed_analog *analog, void *info)
{
int exponent = 0;
float val;

(void)info;

/* serial-dmm will dump the contents of packet by using -l 4 */

/* Defaults */
analog->meaning->mq = SR_MQ_GAIN;
analog->meaning->unit = SR_UNIT_UNITLESS;
analog->meaning->mqflags = 0;

/* Decode sone flags */
if (buf[13] & 0x10)
analog->meaning->mqflags |= SR_MQFLAG_AUTORANGE;
if (buf[13] & 0x40)
analog->meaning->mqflags |= SR_MQFLAG_DC;
if (buf[13] & 0x80)
analog->meaning->mqflags |= SR_MQFLAG_AC;
if (buf[13] & 0x20)
analog->meaning->mqflags |= SR_MQFLAG_RELATIVE;
if (buf[12] & 0x40)
analog->meaning->mqflags |= SR_MQFLAG_HOLD;
if ((buf[13] & 0x0c) == 0x0c)
analog->meaning->mqflags |= SR_MQFLAG_MAX;
if ((buf[13] & 0x0c) == 0x08)
analog->meaning->mqflags |= SR_MQFLAG_MIN;
if ((buf[13] & 0x0c) == 0x0c)
analog->meaning->mqflags |= SR_MQFLAG_AVG;

/* Decode the meter setting. Caution: there may be others on other meters: hFE? */
if (buf[4] == 0x01) {
analog->meaning->mq = SR_MQ_VOLTAGE;
analog->meaning->unit = SR_UNIT_VOLT;
analog->meaning->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS;
}
if (buf[4] == 0x02) {
analog->meaning->mq = SR_MQ_VOLTAGE;
analog->meaning->unit = SR_UNIT_VOLT;
analog->meaning->mqflags |= SR_MQFLAG_DC;
}
/* what is 03 ? */
if (buf[4] == 0x04) {
analog->meaning->mq = SR_MQ_RESISTANCE;
analog->meaning->unit = SR_UNIT_OHM;
}
if (buf[4] == 0x05) {
analog->meaning->mq = SR_MQ_CAPACITANCE;
analog->meaning->unit = SR_UNIT_FARAD;
}
if (buf[4] == 0x06) {
analog->meaning->mq = SR_MQ_TEMPERATURE;
if (buf[10] == 0x08)
analog->meaning->unit = SR_UNIT_CELSIUS;
else
analog->meaning->unit = SR_UNIT_FAHRENHEIT;
}
if (buf[4] == 0x07 || buf[4] == 0x08 ||buf[4] == 0x09) {
analog->meaning->mq = SR_MQ_CURRENT;
analog->meaning->unit = SR_UNIT_AMPERE;
analog->meaning->mqflags |= SR_MQFLAG_DC;
}
/* 0x0a ? 0x0b? */
if (buf[4] == 0x0c || buf[4] == 0x0d || buf[4] == 0x0e) {
analog->meaning->mq = SR_MQ_CURRENT;
analog->meaning->unit = SR_UNIT_AMPERE;
analog->meaning->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS;
}
if (buf[4] == 0x0f) {
analog->meaning->mq = SR_MQ_VOLTAGE;
analog->meaning->unit = SR_UNIT_VOLT;
analog->meaning->mqflags |= SR_MQFLAG_DIODE;
}
if (buf[4] == 0x10) {
if (buf[10] == 0x04) {
analog->meaning->mq = SR_MQ_FREQUENCY;
analog->meaning->unit = SR_UNIT_HERTZ;
}
else {
analog->meaning->mq = SR_MQ_DUTY_CYCLE;
analog->meaning->unit = SR_UNIT_PERCENTAGE;
}
}
if (buf[4] == 0x20) {
analog->meaning->mq = SR_MQ_CONTINUITY;
analog->meaning->unit = SR_UNIT_OHM;
}


val = decode_value(buf, &exponent);
exponent += decode_prefix(buf);
val *= powf(10, exponent);

if (buf[12] & 0x80)
val = -val;

*floatval = val;
analog->encoding->digits = -exponent;
analog->spec->spec_digits = -exponent;

return SR_OK;

}
15 changes: 14 additions & 1 deletion src/hardware/openbench-logic-sniffer/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,18 +150,21 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
g_usleep(RESPONSE_DELAY_US);

if (serial_has_receive_data(serial) == 0) {
serial_close(serial);
sr_dbg("Didn't get any ID reply.");
return NULL;
}

num_read =
serial_read_blocking(serial, buf, 4, serial_timeout(serial, 4));
if (num_read < 0) {
serial_close(serial);
sr_err("Getting ID reply failed (%d).", num_read);
return NULL;
}

if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4)) {
serial_close(serial);
GString *id = sr_hexdump_new((uint8_t *)buf, num_read);

sr_err("Invalid ID reply (got %s).", id->str);
Expand Down Expand Up @@ -380,14 +383,24 @@ static int config_list(uint32_t key, GVariant **data,
{
struct dev_context *devc;
int num_ols_changrp, i;
uint64_t samplerates_ovrd[3];

devc = (sdi) ? sdi->priv : NULL;

switch (key) {
case SR_CONF_SCAN_OPTIONS:
case SR_CONF_DEVICE_OPTIONS:
return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts,
devopts);
case SR_CONF_SAMPLERATE:
*data = std_gvar_samplerates_steps(ARRAY_AND_SIZE(samplerates));
if (!devc)
return SR_ERR_ARG;
samplerates_ovrd[0] = samplerates[0];
samplerates_ovrd[1] = samplerates[1];
samplerates_ovrd[2] = samplerates[2];
if (devc->max_samplerate)
samplerates_ovrd[1] = devc->max_samplerate;
*data = std_gvar_samplerates_steps(ARRAY_AND_SIZE(samplerates_ovrd));
break;
case SR_CONF_TRIGGER_MATCH:
*data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
Expand Down
Loading

0 comments on commit ddb3dcf

Please sign in to comment.