feat: add EskinDeviceFunc FFI bindings and update Python/README
- Add FFI wrappers for all EskinDeviceFunc trait methods: eskin_read_hdw_version, eskin_read_matrix_row/col, eskin_read_device_config1/2, eskin_write_device_config1/2, eskin_write_matrix_row/col - Extract sdk_error_to_code() helper for SdkError -> SdkErrorCode conversion - Update C header (include/eskin_ffi.h) with new function declarations - Update Python FFI bindings (example/python/eskin_ffi.py) with new methods - Update README with Python usage instructions and full FFI interface table
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import ctypes
|
||||
from ctypes import (
|
||||
Structure, POINTER, c_void_p, c_char_p, c_uint8, c_uint16,
|
||||
Structure, POINTER, c_void_p, c_char, c_char_p, c_uint8, c_uint16,
|
||||
c_uint32, c_uint64, c_int16, c_bool
|
||||
)
|
||||
|
||||
LIB_PATH = "./libeskin_finger_sdk.so"
|
||||
|
||||
class EskinSdkVersion(Structure):
|
||||
_fields_ = [
|
||||
@@ -14,8 +15,8 @@ class EskinSdkVersion(Structure):
|
||||
|
||||
|
||||
class EskinDevice:
|
||||
def __init__(self, lib_path: str):
|
||||
self._lib = ctypes.CDLL(lib_path)
|
||||
def __init__(self):
|
||||
self._lib = ctypes.CDLL(LIB_PATH)
|
||||
self._setup_functions()
|
||||
self._handle = None
|
||||
|
||||
@@ -42,6 +43,53 @@ class EskinDevice:
|
||||
c_void_p, c_uint32, POINTER(c_uint8), c_uint16, POINTER(c_uint16)
|
||||
]
|
||||
|
||||
# EskinDeviceFunc bindings
|
||||
|
||||
lib.eskin_read_hdw_version.restype = c_uint32
|
||||
lib.eskin_read_hdw_version.argtypes = [
|
||||
c_void_p, POINTER(c_char), c_uint32, POINTER(c_uint32)
|
||||
]
|
||||
|
||||
lib.eskin_read_matrix_row.restype = c_uint32
|
||||
lib.eskin_read_matrix_row.argtypes = [
|
||||
c_void_p, POINTER(c_uint8)
|
||||
]
|
||||
|
||||
lib.eskin_read_matrix_col.restype = c_uint32
|
||||
lib.eskin_read_matrix_col.argtypes = [
|
||||
c_void_p, POINTER(c_uint8)
|
||||
]
|
||||
|
||||
lib.eskin_read_device_config1.restype = c_uint32
|
||||
lib.eskin_read_device_config1.argtypes = [
|
||||
c_void_p, POINTER(c_uint8)
|
||||
]
|
||||
|
||||
lib.eskin_read_device_config2.restype = c_uint32
|
||||
lib.eskin_read_device_config2.argtypes = [
|
||||
c_void_p, POINTER(c_uint8)
|
||||
]
|
||||
|
||||
lib.eskin_write_device_config1.restype = c_uint32
|
||||
lib.eskin_write_device_config1.argtypes = [
|
||||
c_void_p, c_bool, POINTER(c_uint16)
|
||||
]
|
||||
|
||||
lib.eskin_write_device_config2.restype = c_uint32
|
||||
lib.eskin_write_device_config2.argtypes = [
|
||||
c_void_p, c_bool, POINTER(c_uint16)
|
||||
]
|
||||
|
||||
lib.eskin_write_matrix_row.restype = c_uint32
|
||||
lib.eskin_write_matrix_row.argtypes = [
|
||||
c_void_p, c_uint8, POINTER(c_uint16)
|
||||
]
|
||||
|
||||
lib.eskin_write_matrix_col.restype = c_uint32
|
||||
lib.eskin_write_matrix_col.argtypes = [
|
||||
c_void_p, c_uint8, POINTER(c_uint16)
|
||||
]
|
||||
|
||||
def version(self) -> tuple:
|
||||
v = self._lib.eskin_version()
|
||||
return (v.major, v.minor, v.patch)
|
||||
@@ -79,6 +127,89 @@ class EskinDevice:
|
||||
raise RuntimeError(f"write_register failed: error={err}")
|
||||
return ret.value
|
||||
|
||||
def read_hdw_version(self) -> str:
|
||||
"""读取硬件版本号"""
|
||||
buf = (c_char * 64)()
|
||||
actual = c_uint32(0)
|
||||
err = self._lib.eskin_read_hdw_version(
|
||||
self._handle, buf, len(buf), ctypes.byref(actual)
|
||||
)
|
||||
if err != 0:
|
||||
raise RuntimeError(f"read_hdw_version failed: error={err}")
|
||||
return buf[:actual.value].decode("utf-8")
|
||||
|
||||
def read_matrix_row(self) -> int:
|
||||
"""读取矩阵行数"""
|
||||
out = c_uint8(0)
|
||||
err = self._lib.eskin_read_matrix_row(self._handle, ctypes.byref(out))
|
||||
if err != 0:
|
||||
raise RuntimeError(f"read_matrix_row failed: error={err}")
|
||||
return out.value
|
||||
|
||||
def read_matrix_col(self) -> int:
|
||||
"""读取矩阵列数"""
|
||||
out = c_uint8(0)
|
||||
err = self._lib.eskin_read_matrix_col(self._handle, ctypes.byref(out))
|
||||
if err != 0:
|
||||
raise RuntimeError(f"read_matrix_col failed: error={err}")
|
||||
return out.value
|
||||
|
||||
def read_device_config1(self) -> int:
|
||||
"""读取设备配置寄存器1"""
|
||||
out = c_uint8(0)
|
||||
err = self._lib.eskin_read_device_config1(self._handle, ctypes.byref(out))
|
||||
if err != 0:
|
||||
raise RuntimeError(f"read_device_config1 failed: error={err}")
|
||||
return out.value
|
||||
|
||||
def read_device_config2(self) -> int:
|
||||
"""读取设备配置寄存器2"""
|
||||
out = c_uint8(0)
|
||||
err = self._lib.eskin_read_device_config2(self._handle, ctypes.byref(out))
|
||||
if err != 0:
|
||||
raise RuntimeError(f"read_device_config2 failed: error={err}")
|
||||
return out.value
|
||||
|
||||
def write_device_config1(self, enable: bool) -> int:
|
||||
"""写入设备配置寄存器1"""
|
||||
ret = c_uint16(0)
|
||||
err = self._lib.eskin_write_device_config1(
|
||||
self._handle, enable, ctypes.byref(ret)
|
||||
)
|
||||
if err != 0:
|
||||
raise RuntimeError(f"write_device_config1 failed: error={err}")
|
||||
return ret.value
|
||||
|
||||
def write_device_config2(self, enable: bool) -> int:
|
||||
"""写入设备配置寄存器2"""
|
||||
ret = c_uint16(0)
|
||||
err = self._lib.eskin_write_device_config2(
|
||||
self._handle, enable, ctypes.byref(ret)
|
||||
)
|
||||
if err != 0:
|
||||
raise RuntimeError(f"write_device_config2 failed: error={err}")
|
||||
return ret.value
|
||||
|
||||
def write_matrix_row(self, row: int) -> int:
|
||||
"""写入矩阵行数"""
|
||||
ret = c_uint16(0)
|
||||
err = self._lib.eskin_write_matrix_row(
|
||||
self._handle, row, ctypes.byref(ret)
|
||||
)
|
||||
if err != 0:
|
||||
raise RuntimeError(f"write_matrix_row failed: error={err}")
|
||||
return ret.value
|
||||
|
||||
def write_matrix_col(self, col: int) -> int:
|
||||
"""写入矩阵列数"""
|
||||
ret = c_uint16(0)
|
||||
err = self._lib.eskin_write_matrix_col(
|
||||
self._handle, col, ctypes.byref(ret)
|
||||
)
|
||||
if err != 0:
|
||||
raise RuntimeError(f"write_matrix_col failed: error={err}")
|
||||
return ret.value
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
from eskin_ffi import EskinDevice
|
||||
|
||||
def main():
|
||||
dev = EskinDevice()
|
||||
|
||||
# SDK 版本
|
||||
ver = dev.version()
|
||||
print(f"ESkin SDK version: {ver[0]}.{ver[1]}.{ver[2]}")
|
||||
|
||||
# 打开设备
|
||||
dev.open("/dev/ttyUSB0")
|
||||
print("Device opened")
|
||||
|
||||
try:
|
||||
# 读取硬件版本
|
||||
hdw_ver = dev.read_hdw_version()
|
||||
print(f"Hardware version: {hdw_ver}")
|
||||
|
||||
# 读取矩阵尺寸
|
||||
row = dev.read_matrix_row()
|
||||
col = dev.read_matrix_col()
|
||||
print(f"Matrix size: {row} x {col}")
|
||||
|
||||
# 读取设备配置
|
||||
cfg1 = dev.read_device_config1()
|
||||
# cfg2 = dev.read_device_config2()
|
||||
print(f"Device config1: 0x{cfg1:02X}")
|
||||
# print(f"Device config2: 0x{cfg2:02X}")
|
||||
|
||||
# 写入矩阵尺寸示例
|
||||
# ret = dev.write_matrix_row(16)
|
||||
# print(f"Write matrix row: returned {ret} bytes")
|
||||
# ret = dev.write_matrix_col(16)
|
||||
# print(f"Write matrix col: returned {ret} bytes")
|
||||
|
||||
# 写入设备配置示例
|
||||
# ret = dev.write_device_config1(True)
|
||||
# print(f"Write device config1: returned {ret} bytes")
|
||||
# ret = dev.write_device_config2(False)
|
||||
# print(f"Write device config2: returned {ret} bytes")
|
||||
|
||||
# 原始寄存器读写
|
||||
data = dev.read_register(0x1C00, 168)
|
||||
print(f"Serial number: {data.hex().upper()}")
|
||||
|
||||
finally:
|
||||
dev.close()
|
||||
print("Device closed")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user