hardwareregister
Provide an abstract representation of hardware registers that allows defining registers and fields as a generic description without having to write boilerplate code.
Description of hardware registers.
A register has a name and an offset (which can be an address). It may also have an initial (reset) value.
A register is made up of one or more fields. A field starts at a (low) first bit and ends as a last (high) bit. The bit range is inclusive.
- The bits in the field can be converted to several types:
boolean (one bit only)
enum
integer (unsigned)
A register value holds the value of a register.
The Register describes a register and the fields it contains.
The RegisterValue holds a register value and references a
Register.
Example use
wdt_ctrla = Register('WDT.CTRLA', 0x0100,
RegisterDescription( 8, [
RegisterFieldInt('PERIOD', 0, 3),
RegisterFieldInt('WINDOW', 4, 7)])
)
wdt_status = Register('WDT.STATUS', 0x0101,
RegisterDescription(8, [
RegisterFieldBool('SYNCBUSY', 0),
RegisterFieldBool('LOCK', 7)]),
0)
@enum.unique
class VrefAC0RegSel(enum.IntEnum):
V0_55 = 0x00
V1_1 = 0x01
V2_5 = 0x02
V4_4 = 0x04
res1 = 0x05
res2 = 0x06
AVDD = 0x07
vref_ctrla = Register('VREF.CTRLA', 0x00A0,
RegisterDescription(8, [
RegisterFieldEnum('AC0REFSEL', 0, 2, VrefAC0RegSel)]),
0)
nvmctrl_addr = Register('NVMCTRL.ADDR', 0x1008,
RegisterDescription(16, [
RegisterFieldInt('ADDR', 0, 15, RegisterField.Endian.Big),]),
0)
nvmctrl_addr_value = RegisterValue(nvmctrl_addr, 0x1234)
nvmctrl_addr_value = RegisterValue(nvmctrl_addr, 0x1234)
print(f'nvmctrl_addr_value 0x{nvmctrl_addr_value.value:04x} is {nvmctrl_addr_value}')
nvmctrl_addr_value.value = 0x5678
print(f'nvmctrl_addr_value 0x{nvmctrl_addr_value.value:04x} is {nvmctrl_addr_value}')
Output:
nvmctrl_addr_value 0x1234 is ADDR:4660
nvmctrl_addr_value 0x5678 is ADDR:22136
- class pymisclib.hardwareregister.Register(name: str, offset: int, description: RegisterDescription, initial: int = -1)
A register at an offset with a name and description.
- __init__(name: str, offset: int, description: RegisterDescription, initial: int = -1)
Initialize self.
- Parameters:
name¶ (str) – Name of the register.
offset¶ (int) – Offset of the register.
description¶ (RegisterDescription) – Description of the register.
initial¶ (int) – Initial value of the register after reset. Use -1 for unknown initial value.
- property description: RegisterDescription
Description of the register.
- property initial: int
Initial value of the register after reset. -1 is unknown.
- property name: str
Return the register name.
- property offset: int
Offset of the register in memory.
- class pymisclib.hardwareregister.RegisterDescription(nr_bits: int, fields: list[RegisterField])
Describes the layout and fields of a register.
- __init__(nr_bits: int, fields: list[RegisterField])
Initialize self.
- Parameters:
nr_bits¶ (int) – Number of bits in the register.
fields¶ (list[RegisterField]) – Fields of the register.
- Raises:
IndexError – An error was found in the fields.
KeyError – A field name was used multiple times.
- check_field_consistency()
Check that the fields are consistently defined.
- Raises:
IndexError – An error was found in the fields.
- field(name: str) RegisterField
Return the field with the given name.
- Parameters:
name¶ (str) – Name of the field.
- Raises:
KeyError – The given name is not a field.
- fields_by_end_bit() Generator[RegisterField, None, None]
Yield all register fields in falling order of their end bit.
- Returns:
A register field per call.
- Return type:
- fields_by_start_bit() Generator[RegisterField, None, None]
Yield all register fields in rising order of their start bit.
- Returns:
A register field per call.
- Return type:
- mask_keep_field(field: RegisterField) int
Create a mask to remove all bits not belonging to the field.
- Parameters:
field¶ (RegisterField) – The field to mask.
- Returns:
A mask leaving only the bits belonging to the field.
- mask_remove_field(field: RegisterField) int
Create a mask to remove all bits belonging to the field.
- Parameters:
field¶ (RegisterField) – The field to mask.
- Returns:
A mask removing all bits belonging to the field.
- value_of_field(field: RegisterField, value: int) Any
Return the value of the field in the register.
- class pymisclib.hardwareregister.RegisterField(name: str, first_bit: int = 0, last_bit: int = 31, conversion: Type = None, endian: Endian = Endian.Unknown)
Describe a field in a register.
- class Endian(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Endianness of a register.
- Big = 'BE'
Values are stored with the most significant byte at the lowest address and the least significant byte at the highest address.
- Example ::
0x12345678 is stored as 0x12 0x34 0x56 0x78.
- Litte = 'LE'
Values are stored with the least significant byte at the lowest address and the most significant byte at the highest address.
- Example ::
0x12345678 is stored as 0x78 0x56 0x34 0x12.
- Middle = 'ME'
Values are stored as big endian words where each word is stored as litte endian.
- Example ::
0x12345678 is stored as 0x34 0x12 0x78 0x56.
- Unknown = '??'
The endianness is unknown.
- __init__(name: str, first_bit: int = 0, last_bit: int = 31, conversion: Type = None, endian: Endian = Endian.Unknown)
Initialize the instance.
- Parameters:
name¶ – The name of the field.
first_bit¶ – The first bit of the register belonging to the field (inclusive).
last_bit¶ – The last bit of the register belonging to the field (inclusive).
conversion¶ (TypeVar) – The conversion class.
endian¶ (Endian) – Endianness of the field. This is only relevant for fields spanning byte boundaries.
- Raises:
IndexError – last_bit is smaller than first_bit.
- convert(value: Any) Any
Convert the given value to the type of the field.
- property conversion: Type
Return class used to convert the value.
- property first_bit: int
First bit of the register containing the field.
- property last_bit: int
Last bit of the register containing the field.
- property mask: int
A mask leaving only bits contained in the field.
- property name: str
Name of the field.
- property type: Type
Type of the field.
- class pymisclib.hardwareregister.RegisterFieldBool(name: str, bit: int)
A field in a register that is a single bit.
- class pymisclib.hardwareregister.RegisterFieldEnum(name: str, first_bit: int, last_bit: int, conversion: Type[IntEnum] | Type[IntFlag])
- __init__(name: str, first_bit: int, last_bit: int, conversion: Type[IntEnum] | Type[IntFlag])
Initialize the instance.
- class pymisclib.hardwareregister.RegisterFieldInt(name: str, first_bit: int, last_bit: int, endian: Endian = Endian.Unknown)
A register field containing an integral value.
- __init__(name: str, first_bit: int, last_bit: int, endian: Endian = Endian.Unknown)
Initialize the instance.
- Parameters:
name¶ (str) – Name of the field.
first_bit¶ (int) – First bit of the register containing the field (inclusive).
last_bit¶ (int) – Last bit of the register containing the field (inclusive).
endian¶ (RegisterField.Endian) – Endianness of the field. This is only relevant for fields spanning byte boundaries.
- property max_value: int
Maximum allowed value in the field (inclusive).
- property min_value: int
Minimum allowed value in the field (inclusive).
- pymisclib.hardwareregister.example()
Module demonstration.