Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rigol DS1102Z-E USBTMC read regression #463

Open
ius opened this issue Nov 6, 2024 · 4 comments
Open

Rigol DS1102Z-E USBTMC read regression #463

ius opened this issue Nov 6, 2024 · 4 comments

Comments

@ius
Copy link

ius commented Nov 6, 2024

Recent changes to the USBTMC read implementation break support for Rigol DS1102Z-E (and possibly other Rigol devices).

PR #449 changed the USBTMC response read implementation to assume a transfer is complete once a short packet (i.e. <= usb_recv_ep.wMaxPacketSize) is received based on the following excerpt from the USBTMC spec (§3.3):

The device must always terminate a Bulk-IN transfer by sending a short packet. The short packet
may be zero-length or non zero-length.

Unfortunately, it looks like Rigol does not adhere to this part of the spec - no such packets are sent by my Rigol DS1102Z-E. Which also implies pyvisa never manages to complete a transfer if the transfer is exactly usb_recv_ep.wMaxPacketSize bytes.

Trivial reproducer:

#!/usr/bin/env python3
import pyvisa

rm = pyvisa.ResourceManager('@py')
scope = rm.open_resource(rm.list_resources()[0])

scope.write('WAV:SOUR CH1')
scope.write('WAV:STAR 1')
scope.write('WAV:STOP 128')
data = scope.query_binary_values('WAV:DATA?', datatype='B', expect_termination=False)
print('received:', len(data))

Pyivsa should hang, not even responding to SIGINT.

(As it happens the *IDN? response for my device is also exactly usb_recv_ep.wMaxPacketSize (64) bytes, but that might not be the case for other models)

Note: looks to me @arr-ee might have been experiencing a similar issue on his Siglent device when testing the PR: #449 (comment) - alas, my device is a Rigol and it's on the latest firmware available (00.06.03.SP2).

@ius
Copy link
Author

ius commented Nov 6, 2024

Forgot to mention the original PR author for notification purposes: @hcoffin-vecatom

@hcoffin-vecatom
Copy link
Contributor

hcoffin-vecatom commented Nov 6, 2024

Hmm that is unfortunate. Do you happen to know if the usb_recv_ep.wMaxPacketSize long transfer ends in a newline character? If it does, I think the only ways to fix this issue are either to remove the changes from pr #449 or to implement some kind of special logic for devices that don't adhere to the standard (e.g., check for termination characters at the usb read level), which is annoying at best.

@ius
Copy link
Author

ius commented Nov 6, 2024

If I request >=wMaxPacketSize bytes (using the reproducer, with #449 reverted) only the last transaction (and thus also the full transfer) ends on a newline (not sure whether that's part of the protocol of the WAV:DATA response?).

The old read behavior (which relied on multiple requests, checking for the EOM bit to be set in the transaction) works for my Rigol, but if I understand correctly based on reading #449 it seems like at least some Siglent devices fail to set it?

Then I don't really know how to fix this, other than to consider introducing a Siglent (no EOM case) and/or Rigol (no short packet as last transaction) quirk.

@hcoffin-vecatom
Copy link
Contributor

hcoffin-vecatom commented Nov 6, 2024

As far as I can tell from the examples in the DS1000Z-E-ProgrammingGuide (see screenshot at bottom of this reply) \n (0x0A) is the termination character used by the device. I think it is unlikely to fix things, but if you haven't already, try setting the termination character for pyvisa using

scope.read_termination = '\n'

and use expect_termination=True instead of False. If the termination character isn't set properly then I think that could also be causing your program to hang since Session._read() (pyvisa-py/sessions.py) will return constants.StatusCode.success_max_count_read and MessageBasedResource._read_raw (pyvisa/resources/messagebased.py) would loop forever.

I also want to make sure, when using the old read behavior, are you getting the correct data back, or is some part of it being misinterpreted as a header for the Bulk In message? If you are getting the correct data with the old read behavior then your scope is behaving in a quirky way that is different from the quirkiness of either mine or @arr-ee 's instruments.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants