ltr390uv
101 строка · 5.0 Кб
1# micropython
2# MIT license
3# Copyright (c) 2024 Roman Shevchik goctaprog@gmail.com
4"""представление аппаратного регистра устройства"""
5
6# from sensor_pack_2 import bus_service
7from sensor_pack_2.base_sensor import DeviceEx, get_error_str, check_value8from sensor_pack_2.bitfield import BitFields9
10
11class BaseRegistry:12"""Представление аппаратного регистра. Базовый класс."""13
14def _get_width(self) -> int:15"""Возвращает разрядность регистра по информация из параметра типа BitFields в байтах!"""16mx = max(map(lambda val: val.position.stop, self._fields))17# print(f"DBG: _get_width: {mx}")18return 1 + int((mx - 1)/8)19
20def __init__(self, device: [DeviceEx, None], address: int, fields: BitFields, byte_len: [int, None] = None):21"""device - устройство, которому принадлежит регистр.22address - адрес регистра в памяти устройства.
23fields - битовые поля регистра.
24byte_len - разрядность регистра в байтах!"""
25check_value(byte_len, range(1, 3), get_error_str('byte_len', byte_len, range(1, 3)))26self._device = device27self._address = address28self._fields = fields29# один или два байта!!! Если больше, придется изменить метод read!!!30self._byte_len = byte_len if byte_len else self._get_width()31# проверка битового диапазона поля32# str_err = f"Неверный параметр битового поля!"33_k = 8 * self._byte_len34for field in fields:35check_value(field.position.start, range(_k),36get_error_str('field.position.start', field.position.start, range(_k)))37check_value(field.position.stop - 1, range(_k),38get_error_str('field.position.stop', field.position.stop, range(_k)))39check_value(field.position.step, range(1, 2),40get_error_str('field.position.step', field.position.step, range(1, 2))) # шаг только единица!41#42self._value = 0 # значение, считанное из регистра43
44def __len__(self) -> int:45return len(self._fields)46
47def __getitem__(self, key: str) -> int:48"""Возвращает значение битового поля в виде числа или bool по его имени в виде строки!"""49lnk = self._fields50lnk.field_name = key51# установлю значение, иначе правильной работы не будет!!!52lnk.source = self.value53# возврат54return lnk.get_field_value(validate=False)55
56def __setitem__(self, key: str, value: int) -> int:57"""Устанавливает значение битового поля в виде числа или bool по его имени в виде строки!"""58lnk = self._fields59lnk.field_name = key60# установлю значение, иначе правильной работы не будет!!!61lnk.source = self.value62# установка63_tmp = lnk.set_field_value(value=value)64self._value = _tmp65return _tmp66
67@property68def value(self) -> int:69"""Возвращает значение, считанное из регистра. Из этого значения будут извлекаться значения битовых полей."""70return self._value71
72@property73def byte_len(self) -> int:74"""Возвращает разрядность регистра в байтах"""75return self._byte_len76
77
78class RegistryRO(BaseRegistry):79"""Представление аппаратного регистра. Только для чтения"""80
81def read(self) -> [int, None]:82"""Чтение значения из регистра устройства и запись его в поле класса"""83if not self._device:84return85bl = self._byte_len86by = self._device.read_reg(self._address, bl)87fmt = "B" if 1 == bl else "H"88self._value = self._device.unpack(fmt, by)[0]89# print(f"DBG:read: 0x{self._value:x}; byte len: {bl}; address: {self._address}")90return self._value91
92
93class RegistryRW(RegistryRO):94"""Представление аппаратного регистра. Чтение и запись."""95
96def write(self, value: [int, None] = None):97"""Запись значения в регистр устройства"""98if self._device:99val = value if value else self.value100self._device.write_reg(self._address, val, self._byte_len)101# print(f"DBG:RegistryRW.write: 0x{val:x}")102