Добавить общий API старого CAN terminal

This commit is contained in:
2026-09-04 18:19:07 +03:00
parent d9eb7dd9ad
commit 3c4ac9963d
20 changed files with 941 additions and 1 deletions

View File

@@ -41,6 +41,16 @@ class _AbiGuiFrame(ctypes.Structure):
]
class _AbiBalsamFrame(ctypes.Structure):
_fields_ = [
("device", ctypes.c_uint8),
("direction", ctypes.c_uint8),
("present_mask", ctypes.c_uint8),
("start_address", ctypes.c_uint16),
("values", ctypes.c_uint16 * 3),
]
@dataclass(frozen=True)
class NativeFrame:
sequence: int
@@ -118,6 +128,17 @@ class NativeProtocol:
]
lib.pcan_abi_crc16.argtypes = [ctypes.c_void_p, ctypes.c_size_t]
lib.pcan_abi_crc16.restype = ctypes.c_uint16
lib.pcan_abi_balsam_decode.argtypes = [
ctypes.c_uint32, ctypes.c_void_p, ctypes.c_size_t,
ctypes.POINTER(_AbiBalsamFrame),
]
lib.pcan_abi_balsam_decode.restype = ctypes.c_int
lib.pcan_abi_balsam_device_name.argtypes = [ctypes.c_uint8]
lib.pcan_abi_balsam_device_name.restype = ctypes.c_char_p
lib.pcan_abi_balsam_register_name.argtypes = [
ctypes.c_uint8, ctypes.c_uint16, ctypes.c_void_p, ctypes.c_size_t,
]
lib.pcan_abi_balsam_register_name.restype = ctypes.c_size_t
lib.pcan_abi_frame_encode.argtypes = [
ctypes.c_uint8, ctypes.c_uint8, ctypes.c_uint32,
ctypes.c_void_p, ctypes.c_uint8, ctypes.c_void_p, ctypes.c_size_t,
@@ -178,6 +199,27 @@ class NativeProtocol:
source = (ctypes.c_uint8 * len(data)).from_buffer_copy(data) if data else None
return int(self.lib.pcan_abi_crc16(source, len(data)))
def balsam_decode(self, can_id: int, data: bytes):
source = (ctypes.c_uint8 * len(data)).from_buffer_copy(data) if data else None
output = _AbiBalsamFrame()
status = int(self.lib.pcan_abi_balsam_decode(
can_id, source, len(data), ctypes.byref(output)))
if status != 1:
return status, None
return status, (int(output.device), int(output.direction),
int(output.present_mask), int(output.start_address),
tuple(int(value) for value in output.values))
def balsam_device_name(self, device: int) -> str:
value = self.lib.pcan_abi_balsam_device_name(device)
return value.decode("utf-8") if value else ""
def balsam_register_name(self, device: int, address: int) -> str:
output = ctypes.create_string_buffer(128)
self.lib.pcan_abi_balsam_register_name(
device, address, output, len(output))
return output.value.decode("utf-8")
def encode(self, sequence: int, flags: int, can_id: int, data: bytes) -> bytes:
if len(data) > 8:
raise ValueError("DLC cannot exceed 8 bytes")