Description
===========
For the UsbTmc, the current read and/or read_until and/or read_until_timeout should (try to) return the whole _read_buffer AND whatever the _read_message(timeout) returns, up to their nbytes or message_terminator limits. This is not happening now. Also discard_read should get implemented.
The read method should be modified to work the same way as the QMI_Transport.read base class. It should also start with the existing buffer check
nbuf = len(self._read_buffer)
if nbuf >= nbytes:
# The requested number of bytes are already in the buffer.
# Return them immediately.
ret = bytes(self._read_buffer[:nbytes])
self._read_buffer = self._read_buffer[nbytes:]
return ret
And if no buffer is present, then check the timeout value as now and read-in the buffer.
# USB requires a timeout
if timeout is None:
timeout = self.DEFAULT_READ_TIMEOUT
# Read buffer was too short or is empty - read a new message from the instrument.
self._read_buffer.extend(self._read_message(timeout))
Then re-check the buffer length. By too short buffer length discard buffer and raise exception. By too long data discard buffer after nbytes and return nbytes data like now. And the with nbytes of data return and clear whole data buffer.
The read_until (of the QMI_UsbTmcTransport) command says in the description that the message_terminator is ignored as it is not somehow valid for USBTMC protocol. This means that actually this command should not be implemented and be set with NotImplementedError and the read_until_timeout be implemented instead. The problem here is that instruments using SCPI protocol use ScpiProtocol class where in ask the read_until is used by default. We cannot change this to read_until_timeout there as also other transports can use this and that would mess things up. So, we would need to keep read_until but change the implementation such that it forwards then to read_until_timeout.
NOTE: If there remains partial messages in the self._read_buffer and this keeps messing up the parsing of responses or similar, currently it is up to the user or e.g. implemented QMI driver commands to call discard_read() to reset the buffer.
Set the discard_read method of the QMI_UsbTmcTransport class to clear the current buffer (self._read_buffer = bytes<array>()).
def discard_read():
# We should empty the buffer, or if it is empty, discard the next message from the source
if not len(self._read_buffer):
# Read buffer is empty - read a new message from the instrument.
self._read_message(self.DEFAULT_READ_TIMEOUT)
else:
self._read_buffer = bytes()
Affected components
QMI
All affected drivers in diamondos and qmi - TBD
Description =========== For the UsbTmc, the current
read
and/orread_until
and/orread_until_timeout
should (try to) return the whole_read_buffer
AND whatever the_read_message(timeout)
returns, up to theirnbytes
ormessage_terminator
limits. This is not happening now. Alsodiscard_read
should get implemented.The
read
method should be modified to work the same way as theQMI_Transport.read
base class. It should also start with the existing buffer checkAnd if no buffer is present, then check the timeout value as now and read-in the buffer.
Then re-check the buffer length. By too short buffer length discard buffer and raise exception. By too long data discard buffer after
nbytes
and returnnbytes
data like now. And the withnbytes
of data return and clear whole data buffer.The
read_until
(of theQMI_UsbTmcTransport
) command says in the description that themessage_terminator
is ignored as it is not somehow valid for USBTMC protocol. This means that actually this command should not be implemented and be set withNotImplementedError
and theread_until_timeout
be implemented instead. The problem here is that instruments using SCPI protocol useScpiProtocol
class where inask
theread_until
is used by default. We cannot change this toread_until_timeout
there as also other transports can use this and that would mess things up. So, we would need to keepread_until
but change the implementation such that it forwards then toread_until_timeout
.Set the
discard_read
method of theQMI_UsbTmcTransport
class to clear the current buffer (self._read_buffer = bytes<array>()
).Affected components
QMI All affected drivers in diamondos and qmi - TBD
Modules to be created
N/A
Modules to be modified
qmi.core.transport
Tests to be created/updated
tests.core.test_transport_usbtmc
Documentation to be updated
CHANGELOG.md