ads1115
116 строк · 5.8 Кб
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# 24.04.2024 было-> address: int; стало-> address: [int, None]. Смотри def __init__(...
11
12
13class BaseRegistry:14"""Представление аппаратного регистра. Базовый класс."""15
16def _get_width(self) -> int:17"""Возвращает разрядность регистра по информация из параметра типа BitFields в байтах!"""18mx = max(map(lambda val: val.position.stop, self._fields))19# print(f"DBG: _get_width: {mx}")20return 1 + int((mx - 1)/8)21
22def __init__(self, device: [DeviceEx, None], address: [int, None], fields: BitFields, byte_len: [int, None] = None):23"""device - устройство, которому принадлежит регистр.24address - адрес регистра в памяти устройства.
25fields - битовые поля регистра.
26byte_len - разрядность регистра в байтах!"""
27check_value(byte_len, range(1, 3), get_error_str('byte_len', byte_len, range(1, 3)))28self._device = device29self._address = address30self._fields = fields31# один или два байта!!! Если больше, придется изменить метод read!!!32self._byte_len = byte_len if byte_len else self._get_width()33# проверка битового диапазона поля34# str_err = f"Неверный параметр битового поля!"35_k = 8 * self._byte_len36for field in fields:37check_value(field.position.start, range(_k),38get_error_str('field.position.start', field.position.start, range(_k)))39check_value(field.position.stop - 1, range(_k),40get_error_str('field.position.stop', field.position.stop, range(_k)))41check_value(field.position.step, range(1, 2),42get_error_str('field.position.step', field.position.step, range(1, 2))) # шаг только единица!43#44self._value = 0 # значение, считанное из регистра45
46def _rw_enabled(self) -> bool:47"""Возвращает Истина, когда возможна запись в регистр по шине"""48return self._device is not None and self._address is not None49
50def __len__(self) -> int:51return len(self._fields)52
53def __getitem__(self, key: str) -> int:54"""Возвращает значение битового поля в виде числа или bool по его имени в виде строки!"""55lnk = self._fields56lnk.field_name = key57# установлю значение, иначе правильной работы не будет!!!58lnk.source = self.value59# возврат60return lnk.get_field_value(validate=False)61
62def __setitem__(self, key: str, value: int) -> int:63"""Устанавливает значение битового поля в виде числа или bool по его имени в виде строки!"""64lnk = self._fields65lnk.field_name = key66# установлю значение, иначе правильной работы не будет!!!67lnk.source = self.value68# установка69_tmp = lnk.set_field_value(value=value)70self._value = _tmp71return _tmp72
73@property74def value(self) -> int:75"""Возвращает значение, считанное из регистра. Из этого значения будут извлекаться значения битовых полей."""76return self._value77
78@value.setter79def value(self, new_val: int):80"""Иногда требуется явно присвоить значение полю экземпляра класса. Для удобства использования."""81self._value = new_val82
83@property84def byte_len(self) -> int:85"""Возвращает разрядность регистра в байтах"""86return self._byte_len87
88
89class RegistryRO(BaseRegistry):90"""Представление аппаратного регистра. Только для чтения"""91
92def read(self) -> [int, None]:93"""Чтение значения из регистра устройства и запись его в поле класса"""94if not self._rw_enabled():95return96bl = self._byte_len97by = self._device.read_reg(self._address, bl)98fmt = "B" if 1 == bl else "H"99self._value = self._device.unpack(fmt, by)[0]100# print(f"DBG:read: 0x{self._value:x}; byte len: {bl}; address: {self._address}")101return self._value102
103def __int__(self) -> int:104return self.read()105
106
107class RegistryRW(RegistryRO):108"""Представление аппаратного регистра. Чтение и запись."""109
110def write(self, value: [int, None] = None):111"""Запись значения в регистр устройства.112Если value в None, то метод запишет в регистр значение поля self.value"""
113if self._rw_enabled():114val = value if value else self.value115self._device.write_reg(self._address, val, self._byte_len)116# print(f"DBG:RegistryRW.write: 0x{val:x}")117