AS5600
145 строк · 5.9 Кб
1from sensor_pack_2.bus_service import BusAdapter
2from sensor_pack_2.base_sensor import BaseSensor
3
4
5def bitmask(bit_mask_range: range) -> int:
6"""возвращает битовую маску по занимаемым битам."""
7return sum(map(lambda _x: 1 << _x, bit_mask_range))
8
9
10def get_bf(source: int, mask: range) -> [bool, int]:
11"""Возвращает битовое поле из source c использованием диапазона битовой маски mask"""
12if not mask: # длина битовой маски не может быть меньше одного бита!
13raise ValueError(f"Неверный mask! {mask}")
14val = (source & bitmask(mask)) >> mask.start
15if 1 == len(mask):
16return bool(val)
17return val
18
19
20def get_bf_gen(source: int, masks: iter[range]) -> [bool, int]:
21"""Функция-генератор. Возвращает битовое поле из source c использованием диапазона битовой маски mask"""
22for mask in masks:
23yield get_bf(source, mask)
24
25
26class Aliased:
27def __init__(self, alias: [str]):
28self._alias = alias
29
30@property
31def alias(self) -> str:
32"""Возвращает псевдоним"""
33return self._alias
34
35def __repr__(self) -> str:
36return str(f"Alias: {self._alias}; id: {id(self)}; type: {type(self)}")
37
38
39class AliasedStore:
40def __init__(self, items: tuple[Aliased]):
41self._items = items
42
43def __getitem__(self, item: [str]) -> [Aliased, None]:
44if isinstance(item, str):
45for item in self._items:
46if item.alias == item:
47return item
48
49
50class BitField(Aliased):
51"""Класс для удобной работы с битовым полем."""
52
53def __init__(self, alias: [str, None], rng: range):
54"""alias - псевдоним (для удобства, например "work_mode3:0")
55rng: номера бит бит битового поля. Например range(3) - биты 0, 1, 2; range(2, 4) - биты 2, 3!"""
56super().__init__(alias)
57if not len(rng) or rng.step > 1:
58raise ValueError("Неверный параметр rng!")
59self._alias = alias
60self._start = rng.start # номер младшего бита маски
61self._bitmask = bitmask(rng) # вычисление маски
62
63def set(self, source: int, value: int) -> int:
64"""Записывает value в битовый диапазон в source, начиная с бита self._start.
65Возвращает source с установленным value в битовом диапазоне"""
66_tmp = source & ~self._bitmask # чистка битового диапазона в source
67_tmp |= self._bitmask & (value << self._start) # установка битов в заданном диапазоне
68return _tmp
69
70def get(self, source: int) -> int:
71"""Возвращает значение, находящееся в битовом диапазоне в source."""
72return (source & self._bitmask) >> self._start # выделение маской битового диапазона и его сдвиг вправо
73
74@property
75def mask(self) -> int:
76"""Возвращает битовую маску"""
77return self._bitmask
78
79
80class Registry(Aliased):
81"""Типа аппаратный регистр"""
82def __init__(self, alias: str, address: int, bytes_width=1,
83readable: bool = True, writable: bool = True):
84"""alias - псевдоним
85address - адрес регистра в памяти устройства.
86bytes_width - разрядность в байтах"""
87super().__init__(alias)
88if address < 0 or bytes_width > 2:
89raise ValueError("Неверный параметр address или bytes_width!")
90self._fields = None
91self._address = address
92self._readable = readable # доступ на чтение
93self._writable = writable # доступ на запись
94self._length_in_bytes = bytes_width # разрядность регистра в байтах, 1 - 8 бит, 2 - 16 бит
95# считанное из устройства значение хранит это поле!
96self._value = 0
97
98def init(self, fields: tuple[BitField]):
99"""Заполняет регистр битовыми полями"""
100for field in fields:
101if not isinstance(field, BitField):
102raise ValueError("Неверный тип параметра field!")
103self._fields = fields
104
105@property
106def value(self) -> int:
107return self._value
108
109# @value.setter
110# def value(self, new_val):
111# self._value = new_val
112
113def __getitem__(self, item: [str, int]) -> [BitField, None]:
114"""возвращает BitField класс регистра, по его alias или индексу"""
115if isinstance(item, int):
116return self._fields[item]
117if isinstance(item, str):
118for field in self._fields:
119if field.alias == item:
120return field
121return None
122
123@property
124def readable(self) -> bool:
125return self._readable
126
127@property
128def writable(self) -> bool:
129return self._writable
130
131@property
132def address(self) -> int:
133return self._address
134
135
136class BusDevice(BaseSensor):
137def __init__(self, address: int, adapter: BusAdapter, big_byte_ord: bool):
138super().__init__(adapter, address, big_byte_ord)
139self._regs = None
140
141def init(self, regs: tuple[Registry]):
142for reg in regs:
143if not isinstance(reg, Registry):
144raise ValueError('Ошибка. Элемент неверного типа передан в метод init!')
145self._regs = regs
146