AS5600

Форк
0
/
aliased.py 
145 строк · 5.9 Кб
1
from sensor_pack_2.bus_service import BusAdapter
2
from sensor_pack_2.base_sensor import BaseSensor
3

4

5
def bitmask(bit_mask_range: range) -> int:
6
    """возвращает битовую маску по занимаемым битам."""
7
    return sum(map(lambda _x: 1 << _x, bit_mask_range))
8

9

10
def get_bf(source: int, mask: range) -> [bool, int]:
11
    """Возвращает битовое поле из source c использованием диапазона битовой маски mask"""
12
    if not mask:    # длина битовой маски не может быть меньше одного бита!
13
        raise ValueError(f"Неверный mask! {mask}")
14
    val = (source & bitmask(mask)) >> mask.start
15
    if 1 == len(mask):
16
        return bool(val)
17
    return val
18

19

20
def get_bf_gen(source: int, masks: iter[range]) -> [bool, int]:
21
    """Функция-генератор. Возвращает битовое поле из source c использованием диапазона битовой маски mask"""
22
    for mask in masks:
23
        yield get_bf(source, mask)
24

25

26
class Aliased:
27
    def __init__(self, alias: [str]):
28
        self._alias = alias
29

30
    @property
31
    def alias(self) -> str:
32
        """Возвращает псевдоним"""
33
        return self._alias
34

35
    def __repr__(self) -> str:
36
        return str(f"Alias: {self._alias}; id: {id(self)}; type: {type(self)}")
37

38

39
class AliasedStore:
40
    def __init__(self, items: tuple[Aliased]):
41
        self._items = items
42

43
    def __getitem__(self, item: [str]) -> [Aliased, None]:
44
        if isinstance(item, str):
45
            for item in self._items:
46
                if item.alias == item:
47
                    return item
48

49

50
class BitField(Aliased):
51
    """Класс для удобной работы с битовым полем."""
52

53
    def __init__(self, alias: [str, None], rng: range):
54
        """alias - псевдоним (для удобства, например "work_mode3:0")
55
        rng: номера бит бит битового поля. Например range(3) - биты 0, 1, 2; range(2, 4) - биты 2, 3!"""
56
        super().__init__(alias)
57
        if not len(rng) or rng.step > 1:
58
            raise ValueError("Неверный параметр rng!")
59
        self._alias = alias
60
        self._start = rng.start         # номер младшего бита маски
61
        self._bitmask = bitmask(rng)   # вычисление маски
62

63
    def 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)    # установка битов в заданном диапазоне
68
        return _tmp
69

70
    def get(self, source: int) -> int:
71
        """Возвращает значение, находящееся в битовом диапазоне в source."""
72
        return (source & self._bitmask) >> self._start     # выделение маской битового диапазона и его сдвиг вправо
73

74
    @property
75
    def mask(self) -> int:
76
        """Возвращает битовую маску"""
77
        return self._bitmask
78

79

80
class Registry(Aliased):
81
    """Типа аппаратный регистр"""
82
    def __init__(self, alias: str, address: int, bytes_width=1,
83
                 readable: bool = True, writable: bool = True):
84
        """alias - псевдоним
85
        address - адрес регистра в памяти устройства.
86
        bytes_width - разрядность в байтах"""
87
        super().__init__(alias)
88
        if address < 0 or bytes_width > 2:
89
            raise ValueError("Неверный параметр address или bytes_width!")
90
        self._fields = None
91
        self._address = address
92
        self._readable = readable   # доступ на чтение
93
        self._writable = writable   # доступ на запись
94
        self._length_in_bytes = bytes_width     # разрядность регистра в байтах, 1 - 8 бит, 2 - 16 бит
95
        # считанное из устройства значение хранит это поле!
96
        self._value = 0
97

98
    def init(self, fields: tuple[BitField]):
99
        """Заполняет регистр битовыми полями"""
100
        for field in fields:
101
            if not isinstance(field, BitField):
102
                raise ValueError("Неверный тип параметра field!")
103
        self._fields = fields
104

105
    @property
106
    def value(self) -> int:
107
        return self._value
108

109
#    @value.setter
110
#    def value(self, new_val):
111
#        self._value = new_val
112

113
    def __getitem__(self, item: [str, int]) -> [BitField, None]:
114
        """возвращает BitField класс регистра, по его alias или индексу"""
115
        if isinstance(item, int):
116
            return self._fields[item]
117
        if isinstance(item, str):
118
            for field in self._fields:
119
                if field.alias == item:
120
                    return field
121
            return None
122

123
    @property
124
    def readable(self) -> bool:
125
        return self._readable
126

127
    @property
128
    def writable(self) -> bool:
129
        return self._writable
130

131
    @property
132
    def address(self) -> int:
133
        return self._address
134

135

136
class BusDevice(BaseSensor):
137
    def __init__(self, address: int, adapter: BusAdapter, big_byte_ord: bool):
138
        super().__init__(adapter, address, big_byte_ord)
139
        self._regs = None
140

141
    def init(self, regs: tuple[Registry]):
142
        for reg in regs:
143
            if not isinstance(reg, Registry):
144
                raise ValueError('Ошибка. Элемент неверного типа передан в метод init!')
145
        self._regs = regs
146

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.