Checkpoint EEPROM, firmware analysis and instrument protocol updates
This commit is contained in:
@@ -20,20 +20,42 @@ def _api(name, args, result):
|
||||
return function
|
||||
|
||||
|
||||
def capacity():
|
||||
return int(_api("capacity", [], ct.c_uint32)())
|
||||
def capacity(m95m02=False):
|
||||
return int(_api("capacity_profile", [ct.c_uint], ct.c_uint32)(int(m95m02)))
|
||||
|
||||
|
||||
def write_request(controller, destination, source, length, *, m95m02=False):
|
||||
values = (controller, destination, source, length)
|
||||
if any(type(v) is not int or not 0 <= v <= 0xffffffff for v in values):
|
||||
raise ValueError("Адрес или длина вне диапазона uint32")
|
||||
output = ct.create_string_buffer(18)
|
||||
size = _api("write_profile", [ct.c_uint32]*4 + [ct.c_uint, ct.c_void_p, ct.c_size_t], ct.c_size_t)(
|
||||
*values, int(m95m02), output, len(output))
|
||||
if not size:
|
||||
raise ValueError("LengthLoad или адрес выходит за область прошивки выбранной EEPROM либо пересекает область параметров. "
|
||||
"Предел от адреса 0: AT25256B — 32508 байт, M95M02 — 261884 байт.")
|
||||
return output.raw[:size]
|
||||
|
||||
|
||||
class Reader:
|
||||
def __init__(self, controller, start, length):
|
||||
def __init__(self, controller, start, length, *, block=False, m95m02=False):
|
||||
self.m95m02 = bool(m95m02)
|
||||
if m95m02 and not block:
|
||||
raise ValueError("Для M95M02 необходимо блочное чтение")
|
||||
self.block = block
|
||||
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)
|
||||
result = _api("begin_profile", [ct.c_void_p, ct.c_uint32, ct.c_uint32, ct.c_uint32, ct.c_uint], ct.c_int)(
|
||||
ct.byref(self._state), controller, start, length, int(self.m95m02))
|
||||
if result:
|
||||
raise ValueError("Диапазон вне EEPROM AT25256B: 0…0x7FFF байт; длина должна быть больше нуля")
|
||||
raise ValueError(f"Диапазон вне выбранной EEPROM: 0…0x{capacity(self.m95m02)-1:X}; длина должна быть больше нуля")
|
||||
if block:
|
||||
# Detect an old DLL before the GUI acquires ownership of the port.
|
||||
_api("block_request_profile", [ct.c_void_p, ct.c_void_p, ct.c_size_t, ct.c_uint], ct.c_size_t)
|
||||
_api("block_accept_profile", [ct.c_void_p, ct.c_void_p, ct.c_size_t, ct.c_void_p, ct.c_size_t, ct.c_uint], ct.c_int)
|
||||
self.expected
|
||||
|
||||
@property
|
||||
def received(self): return int(self._state.received)
|
||||
@@ -42,17 +64,26 @@ class Reader:
|
||||
@property
|
||||
def start(self): return int(self._state.start)
|
||||
|
||||
@property
|
||||
def expected(self):
|
||||
if not self.block: return 8
|
||||
return int(_api("block_expected_profile", [ct.c_void_p, ct.c_uint], ct.c_size_t)(ct.byref(self._state), int(self.m95m02)))
|
||||
|
||||
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))
|
||||
args = [ct.c_void_p, ct.c_void_p, ct.c_size_t] + ([ct.c_uint] if self.block else [])
|
||||
extra = [int(self.m95m02)] if self.block else []
|
||||
size = _api("block_request_profile" if self.block else "request", args, ct.c_size_t)(
|
||||
ct.byref(self._state), output, len(output), *extra)
|
||||
return output.raw[:size]
|
||||
|
||||
def accept(self, reply):
|
||||
output = ct.create_string_buffer(2)
|
||||
output = ct.create_string_buffer(240 if self.block else 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))
|
||||
args = [ct.c_void_p, ct.c_void_p, ct.c_size_t, ct.c_void_p, ct.c_size_t] + ([ct.c_uint] if self.block else [])
|
||||
extra = [int(self.m95m02)] if self.block else []
|
||||
size = _api("block_accept_profile" if self.block else "accept", args, ct.c_int)(
|
||||
ct.byref(self._state), reply, len(reply), output, len(output), *extra)
|
||||
if size < 0:
|
||||
errors = {-3: "Неверная длина ответа EEPROM", -4: "Ошибка CRC ответа EEPROM",
|
||||
-5: "Неверный адрес контроллера или команда ответа EEPROM"}
|
||||
|
||||
Reference in New Issue
Block a user