diff --git a/pyharp/device.py b/pyharp/device.py index b4c6f6d..32419fd 100644 --- a/pyharp/device.py +++ b/pyharp/device.py @@ -97,6 +97,7 @@ def disconnect(self) -> None: self._ser.close() def read_who_am_i(self) -> int: + self.log.debug("Requesting whoami.") address = CommonRegisters.WHO_AM_I reply: ReplyHarpMessage = self.send( @@ -271,6 +272,7 @@ def reset_device(self): def send(self, message_bytes: bytearray, dump: bool = True) -> ReplyHarpMessage: """Send a harp message; return the device's reply.""" #print(f"Sending: {repr(message_bytes)}") + self.log.debug(f"sent: {repr(message_bytes)}") self._ser.write(message_bytes) # TODO: handle case where read is None @@ -305,4 +307,4 @@ def get_events(self) -> list[ReplyHarpMessage]: def event_count(self) -> int: """Get the number of events in the event queue.""" - return self._ser.event_q.qsize() \ No newline at end of file + return self._ser.event_q.qsize() diff --git a/pyharp/harp_serial.py b/pyharp/harp_serial.py index 3b9d4a2..57e647e 100644 --- a/pyharp/harp_serial.py +++ b/pyharp/harp_serial.py @@ -48,10 +48,13 @@ def __init__(self, serial_port: str, **kwargs): self._ser, partial(HarpSerialProtocol, self._read_q), ) + self._reader.daemon = True + self._reader.name = f"{serial_port}_harp_serial_reader_worker" self._reader.start() transport, protocol = self._reader.connect() self._parse_thread = threading.Thread( + name=f"{serial_port}_harp_serial_parse_worker", target=self.parse_harp_msgs_threaded, daemon=True, ) diff --git a/pyharp/messages.py b/pyharp/messages.py index e86747a..71194ce 100644 --- a/pyharp/messages.py +++ b/pyharp/messages.py @@ -159,6 +159,9 @@ def WriteU32(address: int, value: int) -> WriteU32HarpMessage: def WriteS32(address: int, value: int) -> WriteS32HarpMessage: return WriteS32HarpMessage(address, value) + def WriteS32Array(address: int, value: list[int]) -> WriteS32HarpMessage: + return WriteS32ArrayHarpMessage(address, value) + @staticmethod def parse(frame: bytearray) -> ReplyHarpMessage: return ReplyHarpMessage(frame) @@ -291,6 +294,9 @@ class ReadU32HarpMessage(ReadHarpMessage): def __init__(self, address: int): super().__init__(PayloadType.U32, address) +class ReadS32HarpMessage(ReadHarpMessage): + def __init__(self, address: int): + super().__init__(PayloadType.S32, address) class ReadS32HarpMessage(ReadHarpMessage): def __init__(self, address: int): @@ -423,3 +429,29 @@ def __init__(self, address: int, value: int | List[int]): @property def payload(self) -> int | List[int]: return int.from_bytes(self._frame[5:9], byteorder="little", signed=True) + + +class WriteU8ArrayMessage(WriteHarpMessage): + def __init__(self, address: int, data_format, value: Union[list, tuple]): + self.data_format = data_format + packed_data = struct.pack(self.data_format, *value) + super().__init__(PayloadType.U8, packed_data, address, + offset=(len(packed_data)-1)) + + @property + def payload(self) -> List[int]: + return struct.unpack('{self.data_format}', self._frame[5:4*self.payload_count])[0] + + +class WriteS32ArrayHarpMessage(WriteHarpMessage): + def __init__(self, address: int, value: int): + self.payload_count = len(value) + super().__init__( + PayloadType.S32, + struct.pack('<{len(value)l', *value), + address, offset=(4*self.payload_count - 1)) + + + @property + def payload(self) -> int: + return struct.unpack('<{self.payload_count}l', self._frame[5:4*self.payload_count])[0]