Skip to content

Commit

Permalink
Merge pull request #6 from harp-tech/gl-dev
Browse files Browse the repository at this point in the history
Add schema reader module
  • Loading branch information
glopesdev authored Nov 2, 2023
2 parents 87b4934 + f4fee24 commit 30640a3
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 4 deletions.
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

0 comments on commit 30640a3

Please sign in to comment.