Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
include LICENSE
include README.md
include README.md
include harp/common.yml
145 changes: 145 additions & 0 deletions harp/common.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# yaml-language-server: $schema=registers.json
registers:
WhoAmI:
address: 0
type: U16
access: Read
description: Specifies the identity class of the device.
HardwareVersionHigh:
address: 1
type: U8
access: Read
description: Specifies the major hardware version of the device.
HardwareVersionLow:
address: 2
type: U8
access: Read
description: Specifies the minor hardware version of the device.
AssemblyVersion:
address: 3
type: U8
access: Read
description: Specifies the version of the assembled components in the device.
CoreVersionHigh:
address: 4
type: U8
access: Read
description: Specifies the major version of the Harp core implemented by the device.
CoreVersionLow:
address: 5
type: U8
access: Read
description: Specifies the minor version of the Harp core implemented by the device.
FirmwareVersionHigh:
address: 6
type: U8
access: Read
description: Specifies the major version of the Harp core implemented by the device.
FirmwareVersionLow:
address: 7
type: U8
access: Read
description: Specifies the minor version of the Harp core implemented by the device.
TimestampSeconds:
address: 8
type: U32
access: [Read, Write, Event]
description: Stores the integral part of the system timestamp, in seconds.
volatile: true
TimestampMicroseconds:
address: 9
type: U16
access: Read
description: Stores the fractional part of the system timestamp, in microseconds.
volatile: true
OperationControl:
address: 10
type: U8
access: Write
description: Stores the configuration mode of the device.
payloadSpec:
OperationMode:
description: Specifies the operation mode of the device.
maskType: OperationMode
mask: 0x3
DumpRegisters:
description: Specifies whether the device should report the content of all registers on initialization.
interfaceType: bool
mask: 0x8
MuteReplies:
description: Specifies whether the replies to all commands will be muted, i.e. not sent by the device.
interfaceType: bool
mask: 0x10
VisualIndicators:
description: Specifies the state of all visual indicators on the device.
maskType: LedState
mask: 0x20
OperationLed:
description: Specifies whether the device state LED should report the operation mode of the device.
maskType: LedState
mask: 0x40
Heartbeat:
description: Specifies whether the device should report the content of the seconds register each second.
maskType: EnableFlag
mask: 0x80
ResetDevice:
address: 11
type: U8
access: Write
maskType: ResetFlags
description: Resets the device and saves non-volatile registers.
DeviceName:
address: 12
type: U8
length: 25
access: Write
description: Stores the user-specified device name.
SerialNumber:
address: 13
type: U16
access: Write
description: Specifies the unique serial number of the device.
ClockConfiguration:
address: 14
type: U8
access: Write
maskType: ClockConfigurationFlags
description: Specifies the configuration for the device synchronization clock.
groupMasks:
OperationMode:
description: Specifies the operation mode of the device.
values:
Standby: 0
Active: 1
Speed: 3
EnableFlag:
description: Specifies whether a specific register flag is enabled or disabled.
values:
Disabled: 0
Enabled: 1
LedState:
description: Specifies the state of an LED on the device.
values:
Off: 0
On: 1
bitMasks:
ResetFlags:
description: Specifies the behavior of the non-volatile registers when resetting the device.
bits:
None: 0
RestoreDefault: 0x1
RestoreEeprom: 0x2
Save: 0x4
RestoreName: 0x8
BootFromDefault: 0x40
BootFromEeprom: 0x80
ClockConfigurationFlags:
description: Specifies configuration flags for the device synchronization clock.
bits:
None: 0
ClockRepeater: 0x1
ClockGenerator: 0x2
RepeaterCapability: 0x8
GeneratorCapability: 0x10
ClockUnlock: 0x40
ClockLock: 0x80
4 changes: 4 additions & 0 deletions harp/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@ class MaskValueItem(BaseModel):
model_config = ConfigDict(
extra='forbid',
)
value: int = Field(..., description='Specifies the numerical mask value.')
description: Optional[str] = Field(
None, description='Specifies a summary description of the mask value function.'
)

def __int__(self):
return self.value


class MaskValue(RootModel[Union[int, MaskValueItem]]):
root: Union[int, MaskValueItem]
Expand Down
6 changes: 3 additions & 3 deletions harp/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def _id_camel_to_snake(id: str):
return _camel_to_snake_regex.sub("_", id).lower()


def _create_bit_parser(mask: Union[int, MaskValueItem]):
def _create_bit_parser(mask: int):
def parser(xs: Series) -> Series:
return (xs & mask) != 0

Expand All @@ -50,7 +50,7 @@ def parser(xs: Series) -> Series:

def _create_bitmask_parser(bitMask: BitMask):
lookup = [
(_id_camel_to_snake(k), _create_bit_parser(v.root))
(_id_camel_to_snake(k), _create_bit_parser(int(v.root)))
for k, v in bitMask.bits.items()
]

Expand All @@ -61,7 +61,7 @@ def parser(df: DataFrame):


def _create_groupmask_lookup(groupMask: GroupMask):
return {v.root: n for n, v in groupMask.values.items()}
return {int(v.root): n for n, v in groupMask.values.items()}


def _create_groupmask_parser(name: str, groupMask: GroupMask):
Expand Down
31 changes: 31 additions & 0 deletions harp/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from os import PathLike
from pathlib import Path
from typing import TextIO, Union
from harp.model import Model, Registers
from pydantic_yaml import parse_yaml_raw_as

_common_yaml_path = Path(__file__).absolute().parent.joinpath("common.yml")


def _read_common_registers(file: Union[str, PathLike, TextIO]) -> Registers:
try:
with open(file) as fileIO:
return _read_common_registers(fileIO)
except TypeError:
return parse_yaml_raw_as(Registers, file.read())


def read_schema(
file: Union[str, PathLike, TextIO], include_common_registers: bool = True
) -> Model:
try:
with open(file) as fileIO:
return read_schema(fileIO, include_common_registers)
except TypeError:
schema = parse_yaml_raw_as(Model, file.read())
if not "WhoAmI" in schema.registers and include_common_registers:
common = _read_common_registers(_common_yaml_path)
schema.registers = dict(common.registers, **schema.registers)
schema.bitMasks = dict(common.bitMasks, **schema.bitMasks)
schema.groupMasks = dict(common.groupMasks, **schema.groupMasks)
return schema