Implement basic functionalities for baylibre-acme. Add support
for common config options, device detection and sample reading.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
We try to find the smallest diff by comparing each diff with
the previously known smallest diff, so initially, this smallest diff
should be INFINITY so that we are sure to find a smaller one.
This fixes the following exception:
sr: rigol-ds: Negative vdiv index: -1.
Caught exception: not applicable
These are available on e.g. Rigol DS1102E (or "upgraded" DS1052E).
Without this, if one of the channels happens to have been set to
one of the missing vdiv settings frontends (e.g. PulseView) will
have some trouble using the scope:
sr: hwdriver: sr_config_get(): key 30012 (vdiv) sdi 0x11bcb70 cg CH1
sr: rigol-ds: Negative vdiv index: -1.
std::exception
Mixing tests for both a boolean and an SR_ERR at the same time is not
really a good idea.
parse_header() actually returns a boolean so only check if it returns FALSE.
This fixes the following gcc-5 warning:
src/input/vcd.c: In function 'receive':
src/input/vcd.c:506:34: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses]
if (!parse_header(in, in->buf) != SR_OK)
^
Inlining can only happen in the same compilation unit where the
function was defined, so there is no sense declaring an inline
function in a header if this function is not defined in this
same header.
This fixes the following gcc-5 warning:
In file included from include/libsigrok/libsigrok.h:1066:0,
from src/version.c:21:
include/libsigrok/proto.h:36:20: warning: inline function 'sr_rational_set' declared but never defined
SR_API inline void sr_rational_set(struct sr_rational *r, uint64_t p, uint64_t q);
^
Commit 5801d558 replaced g_slist_copy_deep() by some incorrect code
that actually leaks the newly allocated memory, instead of doing
a deep copy.
This new version should be more correct, more concise, and it fixes
the following warning:
src/session.c: In function 'sr_packet_copy':
src/session.c:1025:38: warning: passing argument 2 of 'g_slist_foreach' from incompatible pointer type [-Wincompatible-pointer-types]
g_slist_foreach(meta_copy->config, (GCopyFunc)copy_src, NULL);
^
In file included from /usr/include/glib-2.0/glib/gmain.h:26:0,
from /usr/include/glib-2.0/glib/giochannel.h:33,
from /usr/include/glib-2.0/glib.h:54,
from src/session.c:24:
/usr/include/glib-2.0/glib/gslist.h:125:10: note: expected 'GFunc {aka void (*)(void *, void *)}' but argument is of type 'void * (*)(const void *, void *)'
void g_slist_foreach (GSList *list,
^
Add new error code which can be used to notify the user about
general input/output errors.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
(lwla_convert_trigger): Fix trigger mask computation bug introduced
by recent change: Widen constant to 64 bit before shifting so that
channel nunmbers beyond 32 are processed correctly.
By avoiding g_slist_copy_deep() for now, we can easily allow libsigrok
to build against glib 2.32 (less hassle for users of stable/older
distros or OSes).
Gnuplot doesn't have any "official" file name extension(s). It uses
(at least) two different types of files basically:
- "control files": These can have many different somewhat commonly
used extensions such as .gpi, .gnu, .gnuplot, .gp, .plt, .gih,
others. These files don't contain data, only Gnuplot commands such
as 'set yrange [75:105]', 'set ylabel "foo" offset 1', and so on.
- "data files": This is what libsigrok reads and writes. These files
contain actual data to be graphed by Gnuplot (with the help of a
specially-crafted control file, see above). The data is usually in
a tab-separated format. The common file extension is usually .dat,
though many others are possible as well.
- 'struct sr_input *' variables are consistently named 'in'.
- 'struct sr_input_module *' variables are consistently named 'imod'.
- 'struct sr_output *' variables are consistently named 'o'.
- 'struct sr_output_module *' variables are consistently named 'omod'.
Currently (as of date 20150122) an ioctl problem within the
FreeBSD kernel is preventing libusb_get_port_numbers() from working.
Hence calls to libusb_get_port_numbers() will always return 0.
This makes it impossible to establish a physical path the the usb device.
This problem has existed "forever" -
meaning that libusb_get_port_numbers() has never worked.
A fix is committed to FreeBSD "current" head -
and will later be merged (MFC'ed) to maintenance branches.
See: https://svnweb.freebsd.org/base?view=revision&revision=277417
Additionally FreeBSD requires that devices prior to calling
libusb_get_port_numbers() have been opened with libusb_open().
The patch is "forwards-compatible".
Currently it acts specificly to libusb_get_port_numbers()
currently returning 0 on FreeBSD.
In these situations it constructs an artificial path to the device.
When FreeBSD kernels appears with proper working ioctl
supporting libusb_get_port_numbers() the code will construct
proper physical paths for newer kernels - while still generating
artificial physical paths for older defective kernels.
Add new config options to libsigrok - 'averaging', which allows to
enable averaging of samples and 'avg_samples' for setting the number
of samples to be averaged over in each cycle.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This fixes a Doxygen warning:
src/input/input.c:209: warning: The following parameters of sr_input_new(const struct sr_input_module *imod, GHashTable *options) are not documented:
parameter 'imod'
On a Hameg HMO1024 you get incomplete data because the USB transfer takes
longer than the scpi->read_timeout_ms of 1 second that is defined in
scpi_dev_inst_new(). Therefore reset the timeout in sr_scpi_get_string()
whenever the device sends a partial response.
Since every individual measurement is represented by a single frame
and a "sample" isn't all that meaningful concept in this context,
it makes more sense to define possible limit in number of frames.
Make the es51919 driver to support setting a frame limit instead of
a sample limit.
In most, but not all, modes the ES51919 reports two separate
analog values for each measurement sample. These values are
mapped to two separate channels and sent in two separate
packets.
A client program needs a way to determine which results are
parts of the same measurement and also know when a complete
measurement is received so it can process the sample. Use
the frame begin and end packets to separate groups that each
represent a single complete measurement.
When libusb cannot access a device, libusb_get_port_numbers() will return
an error. Check the return code rather than doing invalid pointer
operations (out-of-bound read).
Avoid segfaults at sigrok-cli startup on my setup where some USB devices are
not accessible and also make Valgrind happier.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
All of these error conditions are checked via the unit tests.
Also, add the following missing entries (analog trigger types):
- SR_TRIGGER_RISING
- SR_TRIGGER_EDGE
Use g_malloc0() for small allocations and assume they always
succeed. Simplify error handling in a few places accordingly.
Don't always sanity-check parameters for non-public (SR_PRIV)
functions, we require the developers to invoke them correctly.
This allows further error handling simplifications.
This is a feature restricted to the new analog struct.
By default all the digits available in the encoding struct are printed.
The option "digits", when set to "spec", changes this to print the
number given in the spec struct.
It fills the fields with reasonable default values that should suit
most of the drivers. Drivers are obviously free to override the fields
they want after initializing.
The automatic selections of the measured quantity and equivalent circuit
model are more part of the configuration of the meter than attributes
of the measurement result. To reflect this, model them as config keys
instead of mqflags. This allows a driver that supports remote control to
implement 'set' method for them and has the additional benefit of saveing
two flag bits.
If the number and specs of the device's channels are not static, i.e.
need to be probed, this facility is needed.
Initially this will be used for the Philips PM2800 series, where only
the model returned by *IDN? is needed. However this could also be used
to do actual discovery with vendor-specific SCPI commands.
At least the Rigol DP800 series trigger the beeper when changing
channels remotely. Which gets rather annoying when doing acquisition
on three channels as fast as you can.
Add a driver for the DER EE DE-5000 LCR meter. This meter is based on
the Cyrustek ES51919/ES51920 chipset and communicates with the host
computer via an optional connectivity kit.
The kit uses an optoisolated unidirectional link to connect to the
meter and an USB cable on the host side. Internally the connection is
using the FTDI FT232R USB UART chip i.e. from the host computer point
of view the meter is connected into an RS-232 serial port.
This driver implements just a thin shim layer for registering the
driver and uses the es51919 module for all the actual work.
Add a protocol decoder for the Cyrustek ES51919 LCR meter chip.
This chipset (together with ES51920 front-end) is supposedly used
by multiple different portable LCR meters including at least
DER EE DE-5000, Yihua V&A VA520, Mastech MS5308, Uni-T UT612,
CEM DT-9935 and various OEM rebadges of them.
The communication protocol seems to be implemented on the Cyrustek
chip itself so all the different models are expected to use the
same protocol if they implement a host connection. Unfortunately
the protocol is not available in the public documentation of the
chipset, so this implementation is based on reverse engineering it
from traffic captures.
The actual connection between the meter and the host computer may be
different from meter to meter even when based on the same chip. This
module implements a decoder for the protocol and some common helper
functions for interfacing with the meter via an RS-232 serial port.
This calculates a proper timeout value for blocking writes on the
given serial port, for the given number of bytes. Timeout is based
on a fixed 10ms OS overhead, baud rate, data bits and stop bits.
Set this new parameter to 0 (no timeout) at every call site. This is
consistent with previous behaviour, so cannot cause any regressions.
Waiting forever for a serial operation is clearly always wrong. Without
specific knowledge of each device and driver however, I can't choose
appropriate timeouts for each call. The maintainers of these drivers
will need to do so, and also add appropriate handling of timeouts.
When this commit is merged, a bug should be entered for each driver
that is touched by it.
This cleans up some warnings generated by clang's static analyzer.
The function now also returns SR_ERR to signify the specified filename
does not point to a valid session file.
Other SR_ERR_* returns indicate a session file was found, but loading
failed.
This signifies to the module instance no more input will come. This
will cause the module to process any data it may have buffered. The
SR_DF_END packet will also typically be sent at this time.
When an input module instance has received enough input to fully
populate the struct sr_dev_inst, sdi_ready is set to TRUE and its
receive() method returns immediately. Any remaining received data
is buffered until the next time the function is called.
Previously, sdi->index was used to tell several identical fx2lafw-compatible
devices apart. This was a bit of a hack, so this patch makes it use physical
device connections instead. They're guaranteed to remain the same even if
the USB device reconnects.
These calls are executed from an event handler and were previously nonblocking,
but they have no partial read/write handling. The code is already marked TODO
for improvement.
This call is executed from an event handler and was previously nonblocking,
but has no partial write handling. It sends a short packet so should be OK
to block, most likely the output buffer will be empty anyway.
This call was already nonblocking since the driver opens the port with the
SERIAL_NONBLOCK flag. It only reads one byte, and a zero result is handled
appropriately.
This call was previously explicitly nonblocking, but has no partial write
handling. It sends a short packet so should be OK to block, most likely the
output buffer will be empty anyway.
This call was already nonblocking since the driver opens the port with the
SERIAL_NONBLOCK flag. It only reads one byte, and a zero result is handled
appropriately.
This call is executed from an event handler and was previously nonblocking,
but has no partial write handling. It sends a short packet so should be OK
to block, most likely the output buffer will be empty anyway.
These calls are executed from an event handler and were previously nonblocking,
but have no partial write handling. They send short packets so should be OK to
block, most likely the output buffer will be empty anyway.
Fix error handling for some: serial_write can return any negative error code.
This call was previously nonblocking, but there is no handling of partial
writes. It is called from config_set where it is free to block.
Also fix error handling: serial_write can return any negative error code,
not just -1.
These calls were already nonblocking since the driver opens the port with the
SERIAL_NONBLOCK flag. They only read one byte. A return value of zero is not
handled, but should not occur in theory due to the G_IO_IN check. It might be
good to add handling of a zero return anyway, since I'm not sure if this is
always accurate.
This call was already nonblocking since the driver opens the port with the
SERIAL_NONBLOCK flag. It only reads one byte, and a zero result is handled
appropriately.
These calls are executed from an event handler and were previously nonblocking,
but have no partial write handling. They send short packets so should be OK to
block, most likely the output buffer will be empty anyway.
Also fix error handling for these calls, which seems to have been retained from
previous direct usage of write() to a serial port fd.
These calls were previously nonblocking, but have no partial write handling.
They are made from scan and acquisition_start contexts where they are free
to block.
Remove the SERIAL_NONBLOCK at open, which only applied during scan, since all
calls in the scan are now explicitly blocking.
Also fix error handling for these calls, which appears to have been kept
from a previous direct usage of write() on a serial port fd.
This call was already nonblocking since the driver opens the port with the
SERIAL_NONBLOCK flag. Only one byte is read. The case of 0 being returned
is not handled, but the call is only made if G_IO_IN occurred so in theory,
there should be a byte available. It might be wise to add handling for a
return of 0 nonetheless, as I'm not sure if this is always accurate.
This is an odd one. These calls are made from a receive handler so should not
block, and appear to be setup correctly to handle partial reads or no data
available. However, the driver was not opening the port with SERIAL_NONBLOCK
so these calls would have been blocking. Make them nonblocking.
This call is executed from an event handler and was previously nonblocking,
but has no partial write handling. It sends a short packet so should be OK
to block, most likely the output buffer will be empty anyway.
These calls were already nonblocking since this driver opened the port with
the SERIAL_NONBLOCK flag. Having marked them as such, we can remove the flag.
Also remove an unnecessary reopen of the port to change its blocking status.
This call is executed from an event handler and was previously nonblocking,
but has no partial write handling. It sends a short packet so should be OK
to block, most likely the output buffer will be empty anyway.
This call is executed from an event handler and was previously nonblocking,
but has no partial write handling. It sends a short packet so should be OK
to block, most likely the output buffer will be empty anyway.
This is called at scan time so free to block. There is no partial write
handling and a response is expected afterwards. This should therefore be a
blocking call.
This call is executed from an event handler context was previously
nonblocking, however there is no handling for a partial write.
The output buffer is unlikely to be full and the commands to be sent
are short, so it should be OK to make this a blocking call.
This call is executed at scan time so is free to block. There is no
handling for a partial write and a response is expected immediately
afterwards. It should therefore be a blocking call.
This code implements its own waiting based on baudrate, so the read itself
should be nonblocking. In general it will have been already, since drivers
almost universally use the SERIAL_NONBLOCK flag.
There is currently no way to uniquely identify USB devices in
libsigrok. It uses the "bus.address" scheme which is only
constant as long as the device remains attached to the bus.
In order to allow USB device persistence in PulseView, devices
need to provide a unique identifier even in absence of a
serial number. This function is the first step as it provides
the ability to query the physical location of a USB device.
Every driver now publishes its device option config keys, i.e. the
list fetched with sr_config_list(SR_CONF_DEVICE_OPTIONS), with a
set of flags indicating which methods are implemented by the driver
for that key.
The config keys are OR'ed with any combination of SR_CONF_GET,
SR_CONF_SET and SR_CONF_LIST. These are defined as the high bits
of the uint32_t config key. Clients can OR config keys with
SR_CONF_MASK to strip out these bits. This mask will be kept up to
date if other bits are added to the capabilities list; clients MUST
therefore use SR_CONF_MASK for this.
Some keys don't have capability bits added, such as the informative
device type keys (SR_CONF_MULTIMETER, SR_CONF_OSCILLOSCOPE, ...) and
SR_CONF_CONTINUOUS.
Scan options do not have capabilities bits.
libgpib is the userspace component to linux-gpib's kernel modules that
implement low-level interface drivers.
When libsigrok gets userspace GPIB interface drivers, that backend will
be the "official" scpi_gpib.
From sigrok's point of view, this analyzer has two differences:
* It does not require uploading the firmware.
* It returns garbage in some registers used for sanity checks.
Saleae's software ignores that garbage; sigrok only does if it
specifically detects the mcupro clone.
SR_OK: a match was found.
SR_ERR: no match.
SR_ERR_DATA: a match was found but the module cannot handle the input.
SR_OK_CONTINUE: some module didn't have enough data to be sure.
This returned an array of structs with an NULL-ed element at the end.
The drivers still do this, but the wrappers now make and free a NULL-
terminated array around it.
sr_output_options_free() now takes the pointer returned by
sr_output_options_get(), instead of the module owning it.
Previous runs of dev_acquisition_start() keep the enabled_channels list
populated if they fail. This means that once an invalid channel
configuration was detected, it will be detected again even if the channel
configuration was changed. With this change, the list will be cleared
before being populated so that any stale entries are removed.
Output modules are now guaranteed:
- Every option is always given, with the default value if not supplied
by the user, and is the right GVariantType.
- No invalid options are ever passed.
Audio tools processing WAV failes generally need the samples to be in
the range -1 to +1. The scale option adds postprocessing to any samples
going into a WAV file, by dividing the sample values by the given factor.
The Brymen BM25x series supports the BC-20X that is an opto-isolated
serial cable. The link seems to be unidirectional i.e. when activated
the DMM periodically sends updates to the host while the host cannot
control the DMM in any way.
The protocol is documented in "6000-count-digital-multimeters-r1.pdf"
that is available from the manufacturer. Every 15 byte packet consists
of a bitmap where the bits correspond to segments or symbols on the
LCD display i.e. the DMM essentially sends the contents of its screen
to the host in every update. This driver then decodes the measured
quantity, unit and its value from the bitmap.
This is intended for setting (or getting) the amplitude of a source
which doesn't really have an MQ associated with it, such as the demo
driver's analog channels.