Skip to content

Commit 5bfca2f

Browse files
committed
using pydantic to evaluate and read file
1 parent 1c72848 commit 5bfca2f

File tree

2 files changed

+82
-101
lines changed

2 files changed

+82
-101
lines changed

src/ispprogrammer/ISPConnection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from intelhex import IntelHex
1212
from .IODevices import IODevice, UartDevice
13-
from .parts_definitions import GetPartDescriptor
13+
from .parts_definitions import get_part_descriptor
1414
from . import tools
1515

1616
_log = logging.getLogger("ispprogrammer")
@@ -952,7 +952,7 @@ def SetupChip(
952952
isp.reset()
953953
part_id = isp.ReadPartID()
954954

955-
descriptor: dict[str, str] = GetPartDescriptor(chip_file, part_id)
955+
descriptor: dict[str, str] = get_part_descriptor(chip_file, part_id)
956956
_log.debug(f"{part_id}, {descriptor}")
957957
chip = ChipDescription(descriptor)
958958
chip.CrystalFrequency = crystal_frequency
Lines changed: 80 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,86 @@
1-
"""
2-
Parser for the lpctools file, read into a data frame that is
3-
consistent with other formats
4-
"""
5-
6-
from typing import Dict, List
7-
8-
column_names = [
9-
"part id",
10-
"name",
11-
"FlashStart",
12-
"FlashEnd",
13-
"FlashSize",
14-
"SectorCount",
15-
"ResetVectorOffset",
16-
"RAMStart",
17-
"RAMEnd",
18-
"RAMSize",
19-
"RAMBufferOffset",
20-
"RAMBufferSize",
21-
"UU Encode",
22-
"RAMStartWrite",
23-
]
24-
25-
26-
def read_lpcparts_string(string: str) -> Dict[str, List]:
27-
lpc_tools_column_locations = {
28-
"part id": 0,
29-
"name": 1,
30-
"FlashStart": 2,
31-
"FlashSize": 3,
32-
"SectorCount": 4,
33-
"ResetVectorOffset": 5,
34-
"RAMStart": 6,
35-
"RAMSize": 7,
36-
"RAMBufferOffset": 8,
37-
"RAMBufferSize": 9,
38-
"UU Encode": 10,
39-
}
40-
df_dict: dict[str, list] = {}
41-
for column in lpc_tools_column_locations:
42-
df_dict[column] = []
43-
44-
f = string.splitlines()
45-
for line in f:
46-
if not line.strip() or line.strip()[0] == "#":
1+
import csv
2+
from typing import List, Dict, Any
3+
from pathlib import Path
4+
from pydantic import BaseModel, Field, validator
5+
6+
7+
class LPCPart(BaseModel):
8+
part_id: int = Field(alias="part id")
9+
name: str
10+
FlashStart: int
11+
FlashSize: int
12+
SectorCount: int
13+
ResetVectorOffset: int
14+
RAMStart: int
15+
RAMSize: int
16+
RAMBufferOffset: int
17+
RAMBufferSize: int
18+
UU_Encode: str = Field(alias="UU Encode")
19+
20+
@property
21+
def RAMEnd(self) -> int:
22+
return self.RAMStart + self.RAMSize - 1
23+
24+
@property
25+
def FlashEnd(self) -> int:
26+
return self.FlashStart + self.FlashSize - 1
27+
28+
@property
29+
def RAMStartWrite(self) -> int:
30+
return self.RAMStart + self.RAMBufferOffset
31+
32+
@property
33+
def RAMRange(self) -> tuple[int, int]:
34+
return (self.RAMStart, self.RAMEnd)
35+
36+
@property
37+
def FlashRange(self) -> tuple[int, int]:
38+
return (self.FlashStart, self.FlashEnd)
39+
40+
@validator("name", pre=True)
41+
@classmethod
42+
def strip_name(cls, v):
43+
return v.strip()
44+
45+
46+
def parse_lpcparts_string(s: str) -> List[LPCPart]:
47+
parts = []
48+
reader = csv.reader(s.splitlines())
49+
for row in reader:
50+
if not row or row[0].strip().startswith("#"):
4751
continue
48-
split_line = line.strip().split(",")
49-
for column, index in lpc_tools_column_locations.items():
50-
read = split_line[index].strip()
51-
try:
52-
value: int = int(read, 0)
53-
df_dict[column].append(value)
54-
except ValueError:
55-
df_dict[column].append(read)
56-
57-
df = df_dict
58-
df["RAMEnd"] = [
59-
start + size - 1 for start, size in zip(df["RAMStart"], df["RAMSize"])
60-
]
61-
df["FlashEnd"] = [
62-
start + size - 1 for start, size in zip(df["FlashStart"], df["FlashSize"])
63-
]
64-
df["RAMStartWrite"] = [
65-
start + offset for start, offset in zip(df["RAMStart"], df["RAMBufferOffset"])
66-
]
67-
68-
df["RAMRange"] = list(zip(df["RAMStart"], df["RAMEnd"]))
69-
df["FlashRange"] = list(zip(df["FlashStart"], df["FlashEnd"]))
70-
return df
71-
72-
73-
def ReadChipFile(fname: str) -> dict:
74-
"""
75-
Reads an lpcparts style file to a dataframe
76-
"""
77-
with open(fname, "r") as f:
78-
df = read_lpcparts_string(f.read())
79-
return df
80-
81-
82-
def GetPartDescriptorLine(fname: str, partid: int) -> Dict[str, str]:
83-
entries = ReadChipFile(fname)
84-
for i, line_part_id in enumerate(entries["part id"]):
85-
if partid == line_part_id:
86-
return {key: entries[key][i] for key in entries}
52+
fields = {
53+
"part id": int(row[0], 0),
54+
"name": row[1].strip(),
55+
"FlashStart": int(row[2], 0),
56+
"FlashSize": int(row[3], 0),
57+
"SectorCount": int(row[4], 0),
58+
"ResetVectorOffset": int(row[5], 0),
59+
"RAMStart": int(row[6], 0),
60+
"RAMSize": int(row[7], 0),
61+
"RAMBufferOffset": int(row[8], 0),
62+
"RAMBufferSize": int(row[9], 0),
63+
"UU Encode": row[10].strip(),
64+
}
65+
parts.append(LPCPart(**fields))
66+
return parts
67+
68+
69+
def read_chip_file(fname: str) -> List[LPCPart]:
70+
return parse_lpcparts_string(Path(fname).read_text())
71+
72+
73+
def get_part_descriptor_line(fname: str, partid: int) -> LPCPart:
74+
parts = read_chip_file(fname)
75+
for part in parts:
76+
if part.part_id == partid:
77+
return part
8778
raise ValueError(f"PartId {hex(partid)} not found in {fname}")
8879

8980

90-
def GetPartDescriptor(fname: str, partid: int) -> dict[str, str]:
91-
# FIXME redundant function
92-
descriptor = GetPartDescriptorLine(fname, partid)
93-
return descriptor
81+
def get_part_descriptor(fname: str, partid: int) -> Dict[str, Any]:
82+
return get_part_descriptor_line(fname, partid).dict()
9483

9584

96-
def check_parts_definition_dataframe(df):
97-
"""
98-
Takes the standard layout dataframe, check the field validity.
99-
Works with dict or DataFrame
100-
"""
101-
valid = True
102-
for start, end, size in zip(df["RAMStart"], df["RAMEnd"], df["RAMSize"]):
103-
if end - start + 1 != size:
104-
valid = False
105-
return valid
85+
def check_parts_definition(parts: List[LPCPart]) -> bool:
86+
return all(p.RAMEnd - p.RAMStart + 1 == p.RAMSize for p in parts)

0 commit comments

Comments
 (0)