Hi,
I have rewritten some parts of the C++ API bundled with the GUI as a small Python library for automation tasks and so on...
The message that gets written into the output buffer is quite similiar:
class USBMessage(Structure): class Header(Structure): class Flags(LittleEndianStructure): _fields_ = [("destination", c_ubyte, 2), ("reserved", c_ubyte, 2), ("response", c_ubyte, 2), ("reply", c_ubyte, 1), ("rw", c_ubyte, 1)] _fields_ = [("flags", Flags), ("sequence", c_ubyte), ("length", c_ushort)] class Payload(Union): _fields_ = [("command", c_short), ("data", (c_ubyte * _DATA_MAX_SIZE))] _fields_ = [("header", Header), ("payload", Payload)]
I am using the pyhidapi library for USB communication and writing commands to the EVM works fine but most of the time, reading from the device results in wrong data. Both input and output buffers are the same in the Python and the reference C++ version at any time except after calling the 'read' function.
def _read_message(self): self._reset_input_buffer() msg_length = _USB_MIN_PACKET_SIZE bytes_read = 0 if self._send_message() > 0: while bytes_read < msg_length: data = bytearray(self.read(_USB_MIN_PACKET_SIZE, self._timeout)) dlength = len(data) self._input_buffer[bytes_read:bytes_read+dlength] = data if dlength < 0: return bytes_read elif dlength == 0: return ReturnType.READ_TIMEOUT.value if bytes_read == 0: msg = USBMessage.from_buffer_copy(self._input_buffer) if msg.header.flags.response == ResponseType.BUSY.value: return ReturnType.BUSY.value elif ((msg.header.flags.response == ResponseType.ERROR.value) or (msg.header.length == 0)): return ReturnType.NACK.value msg_length = sizeof(msg.header) + msg.header.length bytes_read += dlength return bytes_read return ReturnType.FAIL.value
If you compare it to the C++-Version, the code is quite similiar. My class inherits the hid.Device class from pyhidapi:
def read(self, size, timeout=None): data = ctypes.create_string_buffer(size) if timeout is None: size = self.__hidcall(hidapi.hid_read, self.__dev, data, size) else: size = self.__hidcall( hidapi.hid_read_timeout, self.__dev, data, size, timeout) return data.raw[:size]
The call to the hid api is exactly the same as used in the GUI code (see USB.cpp). When reading from the device, the resulting header part is often wrong or only the flags are returned. If I run a small sample script to start the scan and poll for the device status, it works every fourth or fifth time but most of the time a header length value of zero is returned (_read_message will then return NACK).
So writing to the device works like a charm but reading not. Any ideas what is wrong with the Python code?
Thank you very much!
Lukas