Добавить идентификацию прошивки и чтение EEPROM Бальзам-167
This commit is contained in:
60
python/protocan/periph28335_eeprom.py
Normal file
60
python/protocan/periph28335_eeprom.py
Normal file
@@ -0,0 +1,60 @@
|
||||
"""Thin binding to the Balsam-167 physical EEPROM reader in the shared C core.
|
||||
|
||||
No address conversion, endian/CRC codec or memory-size inference in this port.
|
||||
The caller owns serial scheduling, timeouts, cancellation and dump file storage.
|
||||
"""
|
||||
import ctypes as ct
|
||||
from .native import get_native_protocol, NativeProtocolUnavailable
|
||||
|
||||
|
||||
class _State(ct.Structure):
|
||||
_fields_ = [(name, ct.c_uint32) for name in ("controller", "start", "length", "received")]
|
||||
|
||||
|
||||
def _api(name, args, result):
|
||||
try:
|
||||
function = getattr(get_native_protocol().lib, "pcan_abi_periph28335_eeprom_" + name)
|
||||
except AttributeError as error:
|
||||
raise NativeProtocolUnavailable("Обновите templates/setprotocol.dll: нет API чтения EEPROM 167") from error
|
||||
function.argtypes, function.restype = args, result
|
||||
return function
|
||||
|
||||
|
||||
def capacity():
|
||||
return int(_api("capacity", [], ct.c_uint32)())
|
||||
|
||||
|
||||
class Reader:
|
||||
def __init__(self, controller, start, length):
|
||||
for value in (controller, start, length):
|
||||
if type(value) is not int or not 0 <= value <= 0xffffffff:
|
||||
raise ValueError("Адрес и длина должны быть неотрицательными целыми числами")
|
||||
self._state = _State()
|
||||
result = _api("begin", [ct.c_void_p, ct.c_uint32, ct.c_uint32, ct.c_uint32], ct.c_int)(
|
||||
ct.byref(self._state), controller, start, length)
|
||||
if result:
|
||||
raise ValueError("Диапазон вне EEPROM AT25256B: 0…0x7FFF байт; длина должна быть больше нуля")
|
||||
|
||||
@property
|
||||
def received(self): return int(self._state.received)
|
||||
@property
|
||||
def length(self): return int(self._state.length)
|
||||
@property
|
||||
def start(self): return int(self._state.start)
|
||||
|
||||
def request(self):
|
||||
output = ct.create_string_buffer(8)
|
||||
size = _api("request", [ct.c_void_p, ct.c_void_p, ct.c_size_t], ct.c_size_t)(
|
||||
ct.byref(self._state), output, len(output))
|
||||
return output.raw[:size]
|
||||
|
||||
def accept(self, reply):
|
||||
output = ct.create_string_buffer(2)
|
||||
reply = bytes(reply)
|
||||
size = _api("accept", [ct.c_void_p, ct.c_void_p, ct.c_size_t, ct.c_void_p, ct.c_size_t], ct.c_int)(
|
||||
ct.byref(self._state), reply, len(reply), output, len(output))
|
||||
if size < 0:
|
||||
errors = {-3: "Неверная длина ответа EEPROM", -4: "Ошибка CRC ответа EEPROM",
|
||||
-5: "Неверный адрес контроллера или команда ответа EEPROM"}
|
||||
raise ValueError(errors.get(size, "Ответ EEPROM не соответствует активному чтению"))
|
||||
return output.raw[:size]
|
||||
Reference in New Issue
Block a user