Skip to content

Commit

Permalink
Fixed bug in USBTMC code which caused issues when packets were longer…
Browse files Browse the repository at this point in the history
… than max usb packet size (#449)

* following USBTMC specification sec. 3.3, updated read function for USBTMC class to correctly handle messages longer than the usb packet size. Created USBIntstrSession read to handle case where an incomplete message is read (i.e., before a term character is reached)

* fixed linting errors

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* allowed suppress_end_en, changed Session_read so it won't hang when suppress_end_en==True

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* removed USBIntrsSession.read

* update changelog

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: MatthieuDartiailh <[email protected]>
  • Loading branch information
3 people authored Oct 1, 2024
1 parent a29b7dc commit 40e1e4b
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ PyVISA-py Changelog
------------------

- add read_stb method for TCPIP HiSLIP client PR #429
- fix usbtmc implementation to respect section 3.3 of the spec PR #449
Read now reads from usb until a "short packet" has been read
(see specification), and only expects a header on the first packet received.
- add support for VI_ATTR_SUPPRESS_END_EN for USB resources PR #449

0.7.2 (07/03/2024)
------------------
Expand Down
10 changes: 8 additions & 2 deletions pyvisa_py/protocols/usbtmc.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,13 +479,19 @@ def read(self, size):
try:
resp = raw_read(recv_chunk + header_size + max_padding)
response = BulkInMessage.from_bytes(resp)
received.extend(response.data)
while len(resp) == self.usb_recv_ep.wMaxPacketSize:
# USBTMC Section 3.3 specifies that the first usb packet
# must contain the header. the remaining packets do not need
# the header the message is finished when a "short packet"
# is sent (one whose length is less than wMaxPacketSize)
resp = raw_read(recv_chunk + header_size + max_padding)
received.extend(resp)
except (usb.core.USBError, ValueError):
# Abort failed Bulk-IN operation.
self._abort_bulk_in(self._btag)
raise

received.extend(response.data)

# Detect EOM only when device sends all expected bytes.
if len(response.data) >= response.transfer_size:
eom = response.transfer_attributes & 1
Expand Down
7 changes: 3 additions & 4 deletions pyvisa_py/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,10 +796,9 @@ def _read(
if current:
out.extend(current)
end_indicator_received = end_indicator_checker(current)
if end_indicator_received:
if not suppress_end_en:
# RULE 6.1.1
return bytes(out), StatusCode.success
if end_indicator_received and not suppress_end_en:
# RULE 6.1.1
return bytes(out), StatusCode.success
else:
if termination_char_en and (term_char in current):
# RULE 6.1.2
Expand Down
5 changes: 0 additions & 5 deletions pyvisa_py/usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,6 @@ def _usb_reader():

supress_end_en, _ = self.get_attribute(ResourceAttribute.suppress_end_enabled)

if supress_end_en:
raise ValueError(
"VI_ATTR_SUPPRESS_END_EN == True is currently unsupported by pyvisa-py"
)

term_char, _ = self.get_attribute(ResourceAttribute.termchar)
term_char_en, _ = self.get_attribute(ResourceAttribute.termchar_enabled)

Expand Down

0 comments on commit 40e1e4b

Please sign in to comment.