@@ -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