From 63bd6158287cf0d19ea370729cb76c7e6c7b37a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:55:16 +0100 Subject: [PATCH 1/4] build(deps): bump codecov/codecov-action from 4 to 5 (#467) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4 to 5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4...v5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b5ffad16..a2f2e993 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,7 @@ jobs: pip install pytest-cov pytest pyvisa_py/testsuite --cov pyvisa_py --cov-report xml - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} flags: unittests From 0d42629aef8e873fb3c236307cfeb7e487533621 Mon Sep 17 00:00:00 2001 From: Matthieu Dartiailh Date: Tue, 17 Dec 2024 08:47:57 +0100 Subject: [PATCH 2/4] attributes: add vicp INSTR to the supported interface for TCPIP keep alive attr (#477) --- pyvisa_py/attributes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyvisa_py/attributes.py b/pyvisa_py/attributes.py index 753d20db..99ba0446 100644 --- a/pyvisa_py/attributes.py +++ b/pyvisa_py/attributes.py @@ -27,4 +27,5 @@ class AttrVI_ATTR_TCPIP_KEEPALIVE(former_keepalive): resources = [ (constants.InterfaceType.tcpip, "SOCKET"), (constants.InterfaceType.tcpip, "INSTR"), + (constants.InterfaceType.vicp, "INSTR"), ] From 8b478188d14d9f9811a3011bdc303e8cb10a593d Mon Sep 17 00:00:00 2001 From: Jimmy van den Bergh <93945571+Jimmyvandenbergh@users.noreply.github.com> Date: Tue, 17 Dec 2024 10:14:48 +0100 Subject: [PATCH 3/4] Support partial usbtmc reads and request the `size` amount of bytes from the device (#470) * updated to support partial usbtmc message reads from device to support IEEE 488.2 arbitrary block reads fixes the requested data to be send in the header instead of recv_chunk. * Speedoptimazation for read, we now use large chuck sizes. * Fix typo in chunck VS chunk * Update release notes --------- Co-authored-by: Matthieu Dartiailh --- CHANGES | 2 + pyvisa_py/protocols/usbtmc.py | 73 +++++++++++++++++++++++------------ 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/CHANGES b/CHANGES index 823fa5a6..91133c39 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,8 @@ PyVISA-py Changelog has been read (see specification), and only expects a header on the first packet received. - fix usbtmc implementation to properly discard the alignment bytes ensuring only the actual data (`transfer_size`) is retained in the message PR #465 +- Implemented partial USBTMC message functionality that allows reading the amount of bytes + specified by host PR #470 - add support for VI_ATTR_SUPPRESS_END_EN for USB resources PR #449 0.7.2 (07/03/2024) diff --git a/pyvisa_py/protocols/usbtmc.py b/pyvisa_py/protocols/usbtmc.py index 8bbac953..da0cc888 100644 --- a/pyvisa_py/protocols/usbtmc.py +++ b/pyvisa_py/protocols/usbtmc.py @@ -12,6 +12,7 @@ """ import enum +import math import struct import time import warnings @@ -455,13 +456,7 @@ def write(self, data): return size def read(self, size): - header_size = 12 - max_padding = 511 - recv_chunk = self.usb_recv_ep.wMaxPacketSize - header_size - - if size > 0 and size < recv_chunk: - recv_chunk = size - + usbtmc_header_size = 12 eom = False raw_read = super(USBTMC, self).read @@ -473,33 +468,61 @@ def read(self, size): received_transfer = bytearray() self._btag = (self._btag % 255) + 1 - req = BulkInMessage.build_array(self._btag, recv_chunk, None) - + req = BulkInMessage.build_array(self._btag, size, None) raw_write(req) try: - resp = raw_read(recv_chunk + header_size + max_padding) + # 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) + chunk_size = ( + math.floor( + (size + usbtmc_header_size) / self.usb_recv_ep.wMaxPacketSize + ) + + 1 + ) * self.usb_recv_ep.wMaxPacketSize + resp = raw_read(chunk_size) + 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(recv_chunk + header_size + max_padding) - received_transfer.extend(resp) # Detect EOM only when device sends all expected bytes. if len(received_transfer) >= response.transfer_size: eom = response.transfer_attributes & 1 - # Truncate data to the specified length (discard padding) - # USBTMC header (12 bytes) has already truncated - received_message.extend(received_transfer[: response.transfer_size]) + if not eom and len(received_transfer) >= size: + # Read asking for 'size' bytes from the device. + # This may be less then the device wants to send back in a message + # Therefore the request does not mean that we must receive a EOM. + # Multiple `transfers` will be required to retrieve the remaining bytes. + eom = True + 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. + chunk_size = ( + math.floor( + (size - len(received_transfer)) + / self.usb_recv_ep.wMaxPacketSize + ) + + 1 + ) * self.usb_recv_ep.wMaxPacketSize + resp = raw_read(chunk_size) + received_transfer.extend(resp) + if len(received_transfer) >= response.transfer_size: + eom = response.transfer_attributes & 1 + if not eom and len(received_transfer) >= size: + eom = True + # Truncate data to the specified length (discard padding) + # USBTMC header (12 bytes) has already truncated + received_message.extend(received_transfer[: response.transfer_size]) except (usb.core.USBError, ValueError): # Abort failed Bulk-IN operation. self._abort_bulk_in(self._btag) From d484ff9ffa9cb7d7df587d4373848f37dc8f4cb3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 19:32:05 +0100 Subject: [PATCH 4/4] [pre-commit.ci] pre-commit autoupdate (#479) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.8.3 → v0.8.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.8.3...v0.8.4) - [github.com/pre-commit/mirrors-mypy: v1.13.0 → v1.14.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.13.0...v1.14.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f06c9cca..eca451a8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,14 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.8.3 + rev: v0.8.4 hooks: # Run the linter. - id: ruff # Run the formatter. - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v1.13.0' # Use the sha / tag you want to point at + rev: 'v1.14.0' # Use the sha / tag you want to point at hooks: - id: mypy additional_dependencies: [numpy, typing_extensions] \ No newline at end of file