Extend the scan code path, accept user provided conn= specs in the
"vid.pid" format. Everything else is assumed to be a hidapi compatible
"path" and may suffer from conn= parser limitations. Unfortunately the
hidapi API won't let us lookup paths from bus.addr specs which would
work when multiple cards need to be told apart.
Rework the scan and probe routines. Skip the USB enumeration's result
set when the user provided a conn= spec, instead exclusively open the
specified device. It's acceptable when this user spec does not match
the details which the hidapi enumeration would yield. [ This version
prepares but does not implement yet support for "funny" hidapi(3) paths
on platforms beyond Linux. ]
This also weakens the logic which determines the relay count from the
USB product string. Any trailing number is accepted. Which allows to use
compatible devices with differing vendor/product strings when conn= is
specified. The previous "USBRelay" prefix check remains in place for
automatic enumeration.
Beautify diagnostics, even phrase debug and spew level messages such
that they can be presented to users. Makes -l 5 look more consistent.
Move all of the sdi creation into the probe routine which communicates
to the relay card. Extend diagnostics in that code path. Which leaves
pure USB enumeration in the scan routine.
Store the USB relay card's serial number such that users can tell apart
multiple connected cards. Hold the HIDAPI path in the 'connection_id'
member because 'conn' is something internal, not for display purposes.
Add the USB identification of the dcttech.com USBRelay<n> card. Which
happens to be shared with other V-USB based firmware projects. Thus is
rather generic. The USB relay card is just the first supported device
of that kind.
Implement support for the "www.dcttech.com USBRelay<n>" card. This V-USB
based HID device communicates HID reports to control up to 8 relays. The
driver depends on the HIDAPI external dependency for maximum portability.
Support for the conn= parameters is limited. A path that HIDAPI can open
is expected, which depends on the platform and HIDAPI implementation,
and may not always be expressed by means of sigrok command line options.
See README.devices for a discussion.
The USB serial number is not considered. This is an implementation
detail of the relay card's firmware. HID reports carry a five character
identifier for the board.
Relay state is cached in the driver. It's assumed that relay state won't
change outside of libsigrok control as long as the device is opened. The
single request to activate/deactivate all relays at once is supported.
The measured quantity flags for the measurement mode can only contain one flag
at maximum. Therefore the quantity flags handling can be simplified, which also
fixes a bug when switching from 4-wire resistance measurement to 2-wire mode.
The HP 3478A device would not reliably identify by means of SCPI queries. The
previous scan() implementation would have matched any connected SCPI device,
then upset these devices by emitting non-SCPI requests.
Tighten the scope of the hp-3478a probe, only scan for devices when a conn=
spec was provided. This avoids false positives and malfunction of other
devices, and still lets users address the problematic device. This is similar
to serial-dmm and unspecific cables and has proven to work there.
Undo the #include statement order change of commit 7414fb55cb. It's
essential on MacOS to include vxi.h early to keep related u_long et al
data types available. See commit d40b8557a9 for a discussion.
Also drop the inclusion of rpc/rpc.h from scpi_vxi.c because it is not
used in that source file, instead is a vxi.h dependency and is included
there.
[ gsi: rephrase commit message ]
The 'sdi' parameter to config API calls can be NULL. Only dereference
after checking its validity.
Reported-By: Alexandre Ferreira <alexandref75@hotmail.com>
Routine scpi_vxi_read_data() invokes device_read_1(), which provides a
static buffer where dynamically allocated memory for SCPI response data
is kept. Release this memory after getting a copy of the response data,
before the next device_read_1() call loses the reference.
Valgrind stats without the fix:
==238825== LEAK SUMMARY:
==238825== definitely lost: 45,547,737 bytes in 18,331 blocks
==238825== indirectly lost: 0 bytes in 0 blocks
==238825== possibly lost: 48,154 bytes in 14 blocks
==238825== still reachable: 42,859 bytes in 288 blocks
==238825== suppressed: 0 bytes in 0 blocks
Valgrind stats with the fix:
==239413== LEAK SUMMARY:
==239413== definitely lost: 40 bytes in 2 blocks
==239413== indirectly lost: 0 bytes in 0 blocks
==239413== possibly lost: 0 bytes in 0 blocks
==239413== still reachable: 38,613 bytes in 287 blocks
==239413== suppressed: 0 bytes in 0 blocks
Remaining leaks in scpi_vxi_open() are of lesser severity because they
don't accumulate during execution.
[ gsi: rebase to recent master, reword commit message ]
Address style nits to improve readablity and future maintenance.
Move system header includes before application level includes. Move
assignments out of variable declaration blocks. Separate function calls
and assignments from error checks and flow control. Break a long line.
Add braces around conditional multi line statements.
All these adjustments are cosmetical. Behaviour does not change.
With Keysight 34465A the VOLT:AC and FREQ functions keep suffering from
USB timeouts and pipe errors. Add a 10ms delay between initiating the
acquisition and checking for completion before fetching the result.
The weird thing is that when successful responses are seen after
temporary failure, enlarging the delay does not make them go away.
Instead the USB errors keep moving to a different spot. Measurements do
arrive though, so this is just annyoing but not a blocker.
sr: [00:00.134038] scpi_usbtmc: Successfully sent SCPI command: 'CONF?'.
sr: [00:00.136043] scpi: Got response: '"FREQ +3.00000000E+00,+3.00000000E-06"', length 38.
sr: [00:00.136119] scpi-dmm: dev_acquisition_start: Precision: '"FREQ +3.00000000E+00,+3.00000000E-06"'
sr: [00:00.136251] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:00.184211] scpi: Got response: '1', length 1.
sr: [00:00.184481] scpi_usbtmc: Successfully sent SCPI command: 'INIT'.
sr: [00:00.234800] session: bus: Received SR_DF_HEADER packet.
cli: Received SR_DF_HEADER.
sr: [00:00.245597] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:01.246050] scpi_usbtmc: USBTMC bulk in transfer error: LIBUSB_ERROR_TIMEOUT.
sr: [00:01.256495] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:01.291871] scpi_usbtmc: USBTMC invalid bulk in header.
sr: [00:01.302392] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:01.401959] scpi: Got response: '1', length 1.
sr: [00:01.402135] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:01.403392] scpi: Got response: '1', length 1.
sr: [00:01.403566] scpi_usbtmc: Successfully sent SCPI command: 'CONF?'.
sr: [00:01.405769] scpi: Got response: '"FREQ +3.00000000E+00,+3.00000000E-06"', length 38.
sr: [00:01.406020] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:01.407500] scpi: Got response: '1', length 1.
sr: [00:01.407674] scpi_usbtmc: Successfully sent SCPI command: 'FETCH?'.
sr: [00:01.409107] scpi: Got response: '+9.00555531E+01', length 15.
Experimentation suggests that 200ms timeouts reduce the probability of
these USB communication errors. But if functions tend to respond that
differently, are delay time specs per MQ required? The implementation of
the driver currently assumes a single delay spec.
Some models are slow to start a measurement acquisition in specific MQs
(meter functions). An "*OPC?" query went unanswered after "INIT" was
sent. This was observed on 34405A in temperature, frequency, resistance,
AC voltage and current mode.
Add an optional per-model measurement delay that is used when the MQ
specifies that the delay is applicable. Because functions are changed
rarely but measurements are taken many times, only the first reading
is delayed while later readings are seen at the expected interval. Not
delaying the first reading will result in device errors.
sr: [00:00.875162] scpi_usbtmc: Successfully sent SCPI command: 'CONF?'.
sr: [00:00.881666] scpi: Got response: '"FREQ +1.00000E+00,+1.00000E-05"', length 32.
sr: [00:00.881700] scpi-dmm: dev_acquisition_start: Precision: '"FREQ +1.00000E+00,+1.00000E-05"'
sr: [00:00.881840] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:00.883966] scpi: Got response: '1', length 1.
sr: [00:00.884139] scpi_usbtmc: Successfully sent SCPI command: 'INIT'.
sr: [00:01.884420] session: bus: Received SR_DF_HEADER packet.
cli: Received SR_DF_HEADER.
sr: [00:01.895260] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:02.895766] scpi_usbtmc: USBTMC bulk in transfer error: LIBUSB_ERROR_TIMEOUT.
sr: [00:02.906302] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:02.910703] scpi_usbtmc: USBTMC invalid bulk in header.
sr: [00:02.921244] scpi_usbtmc: USBTMC bulk out transfer error: LIBUSB_ERROR_PIPE.
sr: [00:02.931802] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:02.932276] scpi: Got response: '1', length 1.
sr: [00:02.932425] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:02.934790] scpi: Got response: '1', length 1.
sr: [00:02.935155] scpi_usbtmc: Successfully sent SCPI command: 'CONF?'.
sr: [00:02.941564] scpi: Got response: '"FREQ +1.00000E+00,+1.00000E-05"', length 32.
sr: [00:00.173408] hwdriver: scpi-dmm: Starting acquisition.
sr: [00:00.173569] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:00.334312] scpi: Got response: '1', length 1.
sr: [00:00.334544] scpi_usbtmc: Successfully sent SCPI command: 'CONF?'.
sr: [00:00.341070] scpi: Got response: '"RES +1.00000E+02,+1.00000E-03"', length 31.
sr: [00:00.341307] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:00.343636] scpi: Got response: '1', length 1.
sr: [00:00.343872] scpi_usbtmc: Successfully sent SCPI command: 'CONF?'.
sr: [00:00.350093] scpi: Got response: '"RES +1.00000E+02,+1.00000E-03"', length 31.
sr: [00:00.350157] scpi-dmm: dev_acquisition_start: Precision: '"RES +1.00000E+02,+1.00000E-03"'
sr: [00:00.350342] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:00.352524] scpi: Got response: '1', length 1.
sr: [00:00.352832] scpi_usbtmc: Successfully sent SCPI command: 'INIT'.
sr: [00:00.352901] session: bus: Received SR_DF_HEADER packet.
cli: Received SR_DF_HEADER.
sr: [00:00.363675] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:01.364363] scpi_usbtmc: USBTMC bulk in transfer error: LIBUSB_ERROR_TIMEOUT.
sr: [00:01.374904] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:02.375380] scpi_usbtmc: USBTMC bulk in transfer error: LIBUSB_ERROR_TIMEOUT.
sr: [00:02.385872] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:03.232457] scpi_usbtmc: USBTMC invalid bulk in header.
sr: [00:03.243003] scpi_usbtmc: USBTMC bulk out transfer error: LIBUSB_ERROR_PIPE.
sr: [00:03.253464] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:03.256568] scpi: Got response: '1', length 1.
sr: [00:03.256902] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:03.259440] scpi: Got response: '1', length 1.
sr: [00:03.259713] scpi_usbtmc: Successfully sent SCPI command: 'CONF?'.
sr: [00:03.266070] scpi: Got response: '"RES +1.00000E+08,+1.00000E+3"', length 30.
sr: [00:03.266456] scpi_usbtmc: Successfully sent SCPI command: '*OPC?'.
sr: [00:03.268501] scpi: Got response: '1', length 1.
sr: [00:03.268961] scpi_usbtmc: Successfully sent SCPI command: 'READ?'.
sr: [00:03.353589] scpi: Got response: '+9.90000000E+37 ', length 16.
Declare a 2500ms measurement initiation delay for 34405A which was found
by experimentation. This is huge but was found to be necessary.
Of course all other meter functions are unaffected by this commit. As
are the meters which specify no delay.
Some models are slow to switch meter functions to specific MQs. This was
observed with 34405A and AC V/I modes, where USB connections timed out
and suffered from pipe errors.
Add an optional delay after "CONF:<mode> [<range>]" SCPI requests. The
duration of the delay is per model, the use of the delay is per MQ on
that model. The 200ms delay for 34405A was found by experimentation.
Speaking about 34405A: Only the "INIT" request in temperature mode
remains as an issue, which is not covered by this commit's approach.
Don't use the "[SENS:]<mode>:RANGE..." request on Agilent protocol
speaking devices. Use "CONF:<mode> [<range>]" instead. This was tested
with all devices which reference this model.
In theory there is the question whether previously configured ranges
should be re-used when (exclusively) the MQ is switched. It's assumed
that this is not useful, instead users or their applications should
select the function first and optionally pick the range then. Re-use of
e.g. 10k resistance range when switching to capacitance might be seen as
confusing (and results in errors in the device).
Use the combination of INIT and FETCH? to get measurements. The READ?
request is more complex and might "undo" what INIT already initiated.
This improves perception of the 34405A meter's operation.
Rephrase the SCPI read timeouts in scpi-dmm model declarations. Shuffle
the order of product terms such that the milliseconds "unit" goes last,
and the milliseconds value goes first. Assume that "2500 * 1000 [us]"
better reflects the intention than "1000 * 2500" does.
The Fluke 45 driver's ECHO_TEST broke other people's SCPI device
identification and was disabled in 2018-11. Remove the dead code which
is impossible to resurrect. Its purpose was questionable to begin with.
Should users be affected, then the echo would break the identification
phase. The check cannot be done before identification without affecting
other connected devices, cannot be done after the identification either
when that very identification systematically fails. Should a user meet
this condition then applications' logs are available to see why *IDN?
fails, assuming that users are not aware of their serial port or device
configuration. The request's reflection in the place of a response gives
a strong hint.
Only scan for hp-3457a devices when the user specified which connection
to use. This avoids breaking SCPI devices by emitting non-standard
requests before reliable device identification.
Only scan for hpib-pps devices when a user provided conn= specification
was given. This avoids breaking SCPI devices by emitting non-standard
requests before reliable device identification.
Improve readability and simplify maintenance of the sr_scpi_scan()
routine.
Move initial assignment and subsequent update of variables in closer
proximity, don't hide assignments in declaration blocks. Use common
helper code where available. Split complex conditions into individual
terms which are easier to review and reason about. Don't mix calls and
value checks and flow control in the same statement.
Device or model or protocol variant specific commands should only be
used after the device reliably got identified. The "CHDR OFF" command
upsets other devices and needs to move after *IDN? and model checks.
The HP 59306A device was made in 1973 and would not reliably identify
by means of SCPI queries. The previous scan() implementation would have
matched any connected SCPI device, then upset these devices by emitting
non-SCPI requests.
Tighten the scope of the hp-59306a probe, only scan for devices when a
conn= spec was provided. This avoids false positives and malfunction of
other devices, and still lets users address the problematic device. This
is similar to serial-dmm and unspecific cables and has proven to work
there.
How to reproduce the issue:
(while any auto enumerating SCPI device is connected)
$ sigrok-cli --scan
Pre-assign default values before having user specified options scanned.
This avoids the necessity to post-process the result. Move the initial
assignment to where its corresponding update is to improve readability.
The sr_serial_extract_options() routine is a hidden gem, has existed for
almost eight years, and is exclusively used by the motech-lps-301 driver
(was also used by hameg-hmo at some point in the past). Being so useful
and doing something to terribly popular, more drivers should use it.
Extend the API to make either of the out parameters genuinely optional,
and guarantee that pre-assigned defaults will survive in the absence of
user specs. Update the Doxygen comment.
While queries for the range are supported for voltage, current,
resistence, capacitance, the same queries in temperature, frequency,
diode, continuity modes not only fail but even lose the USB connection
to the device. This was consistently observed with 34405A and 34465A.
Suppress get and set range requests for the known problematic modes of
the Agilent protocol speaking meters.
Although the 34405A does not support this function, other Agilent
protocol using meters do (currently 34465A, very probably others which
are about to get added in the future).
It's assumed that announcing the availability of that MQ for a set of
meters while only some of them support it is preferrable over exploding
numbers of copies of tables which only slightly vary among each other.
This mechanical edit adds a flags field and the initializer element to
make the compiler happy. Behaviour does not change. See a word diff for
improved review experience.
Add support to get and set the auto/manual range on Agilent protocol
speaking devices (34405A, 34465A). The range values are mere numbers
without a unit or MQ associated with them. Support to list available
ranges is prepared but not used (not needed on these meters). Common
logic could open code the lists of ranges from the model description
if desired in a future implementation.
Though measurement values come in, the 34405A and 34465A meters kept
beeping when acquisition is started. Stopped beeping when the MEAS
keyword was changed to INIT, which is used for other Agilent devices
using the HP protocol variant.
This change is acceptable because it was tested on all DMMs which use
the Agilent protocol (according to scpi-dmm profiles).