Skip to content

Commit

Permalink
Speedoptimazation for read, we now use large chuck sizes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jimmyvandenbergh committed Dec 2, 2024
1 parent 7fc0e7e commit ca8df6c
Showing 1 changed file with 40 additions and 16 deletions.
56 changes: 40 additions & 16 deletions pyvisa_py/protocols/usbtmc.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"""

import enum
import math

Check warning on line 15 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L15

Added line #L15 was not covered by tests
import struct
import time
import warnings
Expand Down Expand Up @@ -455,6 +456,7 @@ def write(self, data):
return size

def read(self, size):
usbtmc_header_size = 12

Check warning on line 459 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L459

Added line #L459 was not covered by tests
eom = False

raw_read = super(USBTMC, self).read
Expand All @@ -467,25 +469,23 @@ def read(self, size):
self._btag = (self._btag % 255) + 1

req = BulkInMessage.build_array(self._btag, size, None)

Check warning on line 471 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L471

Added line #L471 was not covered by tests

raw_write(req)

try:
resp = raw_read(self.usb_recv_ep.wMaxPacketSize)
# make sure the data request is in multitudes of wMaxPacketSize.
# + 1 * wMaxPacketSize for message sizes that equals wMaxPacketSize == size + usbtmc_header_size.
# This to be able to retrieve a short package to end communication
# (see USB 2.0 Section 5.8.3 and USBTMC Section 3.3)
chunck_size = (

Check warning on line 479 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L479

Added line #L479 was not covered by tests
math.floor(
(size + usbtmc_header_size) / self.usb_recv_ep.wMaxPacketSize
)
+ 1
) * self.usb_recv_ep.wMaxPacketSize
resp = raw_read(chunck_size)

Check warning on line 485 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L485

Added line #L485 was not covered by tests

response = BulkInMessage.from_bytes(resp)
received_transfer.extend(response.data)
while (
len(resp) == self.usb_recv_ep.wMaxPacketSize
or len(received_transfer) < response.transfer_size
):
# 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)
# wMaxPacketSize may be incorrectly reported by certain drivers.
# Therefore, continue reading until the transfer_size is reached.
resp = raw_read(self.usb_recv_ep.wMaxPacketSize)
received_transfer.extend(resp)

# Detect EOM only when device sends all expected bytes.
if len(received_transfer) >= response.transfer_size:
Expand All @@ -496,8 +496,32 @@ def read(self, size):
# Therefore the request does not mean that we must receive a EOM.
# Multiple `transfers` will be required to retrieve the remaining bytes.
eom = True

Check warning on line 498 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L498

Added line #L498 was not covered by tests
# Truncate data to the specified length (discard padding)
# USBTMC header (12 bytes) has already truncated
else:
while (
(len(resp) % self.usb_recv_ep.wMaxPacketSize) == 0
or len(received_transfer) < response.transfer_size
) and not eom:
# 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)
# wMaxPacketSize may be incorrectly reported by certain drivers.
# Therefore, continue reading until the transfer_size is reached.
chunck_size = (

Check warning on line 510 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L510

Added line #L510 was not covered by tests
math.floor(
(size - len(received_transfer))
/ self.usb_recv_ep.wMaxPacketSize
)
+ 1
) * self.usb_recv_ep.wMaxPacketSize
resp = raw_read(chunck_size)
received_transfer.extend(resp)

Check warning on line 518 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L517-L518

Added lines #L517 - L518 were not covered by tests
if len(received_transfer) >= response.transfer_size:
eom = response.transfer_attributes & 1

Check warning on line 520 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L520

Added line #L520 was not covered by tests
if not eom and len(received_transfer) >= size:
eom = True

Check warning on line 522 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L522

Added line #L522 was not covered by tests
# Truncate data to the specified length (discard padding)
# USBTMC header (12 bytes) has already truncated
received_message.extend(received_transfer[: response.transfer_size])

Check warning on line 525 in pyvisa_py/protocols/usbtmc.py

View check run for this annotation

Codecov / codecov/patch

pyvisa_py/protocols/usbtmc.py#L525

Added line #L525 was not covered by tests
except (usb.core.USBError, ValueError):
# Abort failed Bulk-IN operation.
Expand Down

0 comments on commit ca8df6c

Please sign in to comment.