| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- from dataclasses import dataclass
- from flipper.utils.openocd import OpenOCD
- @dataclass
- class RegisterBitDefinition:
- name: str
- offset: int
- size: int
- value: int = 0
- class Register32:
- def __init__(self, address: int, definition_list: list[RegisterBitDefinition]):
- self.__dict__["names"] = [definition.name for definition in definition_list]
- self.names = [definition.name for definition in definition_list] # typecheck
- self.address = address
- self.definition_list = definition_list
- # Validate that the definitions are not overlapping
- for i in range(len(definition_list)):
- for j in range(i + 1, len(definition_list)):
- if self._is_overlapping(definition_list[i], definition_list[j]):
- raise ValueError("Register definitions are overlapping")
- self.freezed = True
- def _is_overlapping(
- self, a: RegisterBitDefinition, b: RegisterBitDefinition
- ) -> bool:
- if a.offset + a.size <= b.offset:
- return False
- if b.offset + b.size <= a.offset:
- return False
- return True
- def _get_definition(self, name: str) -> RegisterBitDefinition:
- for definition in self.definition_list:
- if definition.name == name:
- return definition
- raise ValueError(f"Register definition '{name}' not found")
- def get_definition_list(self) -> list[RegisterBitDefinition]:
- return self.definition_list
- def get_address(self) -> int:
- return self.address
- def set_reg_value(self, name: str, value: int):
- definition = self._get_definition(name)
- if value > (1 << definition.size) - 1:
- raise ValueError(
- f"Value {value} is too large for register definition '{name}'"
- )
- definition.value = value
- def get_reg_value(self, name: str) -> int:
- definition = self._get_definition(name)
- return definition.value
- def __getattr__(self, attr):
- if str(attr) in self.names:
- return self.get_reg_value(str(attr))
- else:
- return self.__dict__[attr]
- def __setattr__(self, attr, value):
- if str(attr) in self.names:
- self.set_reg_value(str(attr), value)
- else:
- if attr in self.__dict__ or "freezed" not in self.__dict__:
- self.__dict__[attr] = value
- else:
- raise AttributeError(f"Attribute '{attr}' not found")
- def __dir__(self):
- return self.names
- def set(self, value: int):
- for definition in self.definition_list:
- definition.value = (value >> definition.offset) & (
- (1 << definition.size) - 1
- )
- def get(self) -> int:
- value = 0
- for definition in self.definition_list:
- value |= definition.value << definition.offset
- return value
- def load(self, openocd: OpenOCD):
- self.set(openocd.read_32(self.address))
- def store(self, openocd: OpenOCD):
- openocd.write_32(self.address, self.get())
|