Skip to content

Commit 12e36ca

Browse files
bors[bot]burrbull
andauthored
Merge #54
54: field array collect r=adamgreig a=burrbull Need to test Preferably using rust-embedded/svd2rust#503 Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 0b5ec50 + 4ee70db commit 12e36ca

File tree

4 files changed

+117
-49
lines changed

4 files changed

+117
-49
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## [Unreleased]
44

5+
* Support for collecting fields in field arrays
6+
* Deriving fields
7+
58
## [v0.1.13] 2021-04-16
69

710
* Fix use of `vendorExtensions` tag in SVD files (#53)

example/common_patches/tsc/tsc.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
TSC:
22
_array:
33
IOG?CR: {}
4+
IOHCR:
5+
_array:
6+
G1_IO?: {}
7+
G2_IO*:
8+
_derivedFrom: "G1_IO1"

svdtools/mmap.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,7 @@ def iter_fields(rtag):
5454
return fields.findall("field")
5555

5656

57-
ACCESS = {
58-
"read-only": "ro",
59-
"read-write": "rw",
60-
"write-only": "wo",
61-
}
57+
ACCESS = {"read-only": "ro", "read-write": "rw", "write-only": "wo"}
6258

6359

6460
def get_access(tag):

svdtools/patch.py

Lines changed: 108 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -892,11 +892,17 @@ def collect_in_array(self, rspec, rmod):
892892
for rtag, _, _ in registers[1:]:
893893
self.ptag.find("registers").remove(rtag)
894894
rtag = registers[0][0]
895+
nametag = rtag.find("name")
895896
if "name" in rmod:
896897
name = rmod["name"]
897898
else:
898899
name = rspec[:li] + "%s" + rspec[len(rspec) - ri :]
899-
rtag.find("name").text = name
900+
if dimIndex[0] == "0":
901+
desc = rtag.find("description")
902+
desc.text = desc.text.replace(
903+
nametag.text[li : len(nametag.text) - ri], "%s"
904+
)
905+
nametag.text = name
900906
self.process_register(name, rmod)
901907
ET.SubElement(rtag, "dim").text = str(dim)
902908
ET.SubElement(rtag, "dimIncrement").text = hex(dimIncrement)
@@ -1021,6 +1027,10 @@ def process_register(self, rspec, register, update_fields=True):
10211027
if not fspec.startswith("_"):
10221028
field = register[fspec]
10231029
r.process_field(pname, fspec, field)
1030+
# Handle field arrays
1031+
for fspec in register.get("_array", {}):
1032+
fmod = register["_array"][fspec]
1033+
r.collect_fields_in_array(fspec, fmod)
10241034
if rcount == 0:
10251035
raise MissingRegisterError("Could not find {}:{}".format(pname, rspec))
10261036

@@ -1134,6 +1144,56 @@ def merge_fields(self, fspec):
11341144
ET.SubElement(fnew, "bitOffset").text = str(bitoffset)
11351145
ET.SubElement(fnew, "bitWidth").text = str(bitwidth)
11361146

1147+
def collect_fields_in_array(self, fspec, fmod):
1148+
"""Collect same fields in peripheral into register array."""
1149+
fields = []
1150+
li, ri = spec_ind(fspec)
1151+
for ftag in list(self.iter_fields(fspec)):
1152+
fname = ftag.findtext("name")
1153+
fields.append(
1154+
[ftag, fname[li : len(fname) - ri], int(ftag.findtext("bitOffset"), 0)]
1155+
)
1156+
dim = len(fields)
1157+
if dim == 0:
1158+
raise SvdPatchError(
1159+
"{}: fields {} not found".format(self.rtag.findtext("name"), fspec)
1160+
)
1161+
fields = sorted(fields, key=lambda f: f[2])
1162+
1163+
if fmod.get("_start_from_zero", ""):
1164+
dimIndex = ",".join([str(i) for i in range(dim)])
1165+
else:
1166+
if dim == 1:
1167+
dimIndex = "{0}-{0}".format(fields[0][1])
1168+
else:
1169+
dimIndex = ",".join(f[1] for f in fields)
1170+
offsets = [f[2] for f in fields]
1171+
dimIncrement = 0
1172+
if dim > 1:
1173+
dimIncrement = offsets[1] - offsets[0]
1174+
1175+
if not check_offsets(offsets, dimIncrement):
1176+
raise SvdPatchError(
1177+
"{}: fields cannot be collected into {} array".format(
1178+
self.rtag.findtext("name"), fspec
1179+
)
1180+
)
1181+
for ftag, _, _ in fields[1:]:
1182+
self.rtag.find("fields").remove(ftag)
1183+
ftag = fields[0][0]
1184+
nametag = ftag.find("name")
1185+
if "name" in fmod:
1186+
name = fmod["name"]
1187+
else:
1188+
name = fspec[:li] + "%s" + fspec[len(fspec) - ri :]
1189+
desc = ftag.find("description")
1190+
desc.text = desc.text.replace(nametag.text[li : len(nametag.text) - ri], "%s")
1191+
nametag.text = name
1192+
# self.process_field(name, fmod)
1193+
ET.SubElement(ftag, "dim").text = str(dim)
1194+
ET.SubElement(ftag, "dimIndex").text = dimIndex
1195+
ET.SubElement(ftag, "dimIncrement").text = hex(dimIncrement)
1196+
11371197
def split_fields(self, fspec):
11381198
"""split all fspec in rtag."""
11391199
fields = list(self.iter_fields(fspec))
@@ -1179,56 +1239,60 @@ def process_field_enum(self, pname, fspec, field, usage="read-write"):
11791239

11801240
derived, enum, enum_name, enum_usage = None, None, None, None
11811241
for ftag in self.iter_fields(fspec):
1182-
name = ftag.find("name").text
1183-
1184-
if enum is None:
1185-
enum = make_enumerated_values(name, field, usage=usage)
1186-
enum_name = enum.find("name").text
1187-
enum_usage = enum.find("usage").text
1188-
1189-
for ev in ftag.iter("enumeratedValues"):
1190-
if len(ev) > 0:
1191-
ev_usage_tag = ev.find("usage")
1192-
ev_usage = (
1193-
ev_usage_tag.text if ev_usage_tag is not None else "read-write"
1194-
)
1195-
else:
1196-
# This is a derived enumeratedValues => Try to find the
1197-
# original definition to extract its <usage>
1198-
derived_name = ev.attrib["derivedFrom"]
1199-
derived_enums = self.rtag.findall(
1200-
"./fields/field/enumeratedValues/[name='{}']".format(
1201-
derived_name
1202-
)
1203-
)
1242+
if "_derivedFrom" in field:
1243+
derived = field["_derivedFrom"]
1244+
else:
1245+
name = ftag.find("name").text
12041246

1205-
if derived_enums == []:
1206-
raise SvdPatchError(
1207-
"{}: field {} derives enumeratedValues {} which could not be found".format(
1208-
pname, name, derived_name
1209-
)
1247+
if derived is None:
1248+
if enum is None:
1249+
enum = make_enumerated_values(name, field, usage=usage)
1250+
enum_name = enum.find("name").text
1251+
enum_usage = enum.find("usage").text
1252+
1253+
for ev in ftag.iter("enumeratedValues"):
1254+
if len(ev) > 0:
1255+
ev_usage_tag = ev.find("usage")
1256+
ev_usage = (
1257+
ev_usage_tag.text
1258+
if ev_usage_tag is not None
1259+
else "read-write"
12101260
)
1211-
elif len(derived_enums) != 1:
1212-
raise SvdPatchError(
1213-
"{}: field {} derives enumeratedValues {} which was found multiple times".format(
1214-
pname, name, derived_name
1261+
else:
1262+
# This is a derived enumeratedValues => Try to find the
1263+
# original definition to extract its <usage>
1264+
derived_name = ev.attrib["derivedFrom"]
1265+
derived_enums = self.rtag.findall(
1266+
"./fields/field/enumeratedValues/[name='{}']".format(
1267+
derived_name
12151268
)
12161269
)
12171270

1218-
ev_usage = derived_enums[0].find("usage").text
1219-
1220-
if ev_usage == enum_usage or ev_usage == "read-write":
1221-
if replace_if_exists:
1222-
ftag.remove(ev)
1223-
else:
1224-
print(pname, fspec, field)
1225-
raise SvdPatchError(
1226-
"{}: field {} already has enumeratedValues for {}".format(
1227-
pname, name, ev_usage
1271+
if derived_enums == []:
1272+
raise SvdPatchError(
1273+
"{}: field {} derives enumeratedValues {} which could not be found".format(
1274+
pname, name, derived_name
1275+
)
1276+
)
1277+
elif len(derived_enums) != 1:
1278+
raise SvdPatchError(
1279+
"{}: field {} derives enumeratedValues {} which was found multiple times".format(
1280+
pname, name, derived_name
1281+
)
12281282
)
1229-
)
12301283

1231-
if derived is None:
1284+
ev_usage = derived_enums[0].find("usage").text
1285+
1286+
if ev_usage == enum_usage or ev_usage == "read-write":
1287+
if replace_if_exists:
1288+
ftag.remove(ev)
1289+
else:
1290+
print(pname, fspec, field)
1291+
raise SvdPatchError(
1292+
"{}: field {} already has enumeratedValues for {}".format(
1293+
pname, name, ev_usage
1294+
)
1295+
)
12321296
ftag.append(enum)
12331297
derived = enum_name
12341298
else:

0 commit comments

Comments
 (0)