diff --git a/svd/svd.py b/svd/svd.py index fb44296..0225136 100644 --- a/svd/svd.py +++ b/svd/svd.py @@ -176,8 +176,8 @@ class SvdPeripheral(NamedTuple): disableCondition: str baseAddress: int registerProperties: SvdRegisterProperties - addressBlock: SvdAddressBlock - interrupt: SvdInterrupt + addressBlock: Sequence[SvdAddressBlock] + interrupt: Sequence[SvdInterrupt] registers: Sequence[Union[SvdRegister, SvdCluster]] @@ -198,5 +198,16 @@ class SvdDevice(NamedTuple): peripherals: Sequence[SvdPeripheral] vendorExtensions: Any + def __eq__(self, other): + return self.vendor == other.vendor and self.vendorID == other.vendorID \ + and self.name == other.name and self.series == other.series and \ + self.version == other.version and self.description == other.description \ + and self.licenseText == other.licenseText and self.cpu == other.cpu \ + and self.headerSystemFilename == other.headerSystemFilename and \ + self.headerDefinitionsPrefix == other.headerDefinitionsPrefix and \ + self.addressUnitBits == other.addressUnitBits and self.width == other.width \ + and self.registerProperties == other.registerProperties and \ + self.peripherals == other.peripherals + # TODO: functions for expanding/flattening registerProperties, dimElements and derivedFrom? diff --git a/svd/svdgen.py b/svd/svdgen.py index 4247521..cae5232 100644 --- a/svd/svdgen.py +++ b/svd/svdgen.py @@ -1,19 +1,18 @@ +import xml, xml.etree +import xml.etree.ElementTree as ET import typing, collections.abc from svd import * from typing import get_type_hints -# FIXME: -# * peripheral registers not emitting - - def ser_one(v) -> str: assert v is not None if isinstance(v, bool): return "true" if v else "false" elif isinstance(v, int): return hex(v) - elif isinstance(v, str): return v + elif isinstance(v, str): + return v.replace('&', "&").replace('<', "<").replace('>', ">") elif type(v) == tuple: return "r%dp%d" % (v[0], v[1]) else: return None @@ -47,9 +46,17 @@ type2tag = { SvdPeripheral: 'peripheral', SvdDevice: 'device', } +flattenchildren = { + SvdEnumeratedValues: {'enumeratedValue'}, + SvdCluster: {'cluster','register'}, + SvdDimArrayIndex: {'enumeratedValue'}, + SvdPeripheral: {'interrupt','addressBlock'}, +} -def gen_generic(f, svdelem, T, tag, attrs=(), extraattr="", no_outer=False): +def gen_generic(f, svdelem, T: type, tag: str, attrs=(), extraattr="", no_outer=False, rec=[]): + rec=[*rec, tag] + #print(rec, T, type(svdelem)) atdict={} childdict={} @@ -71,18 +78,33 @@ def gen_generic(f, svdelem, T, tag, attrs=(), extraattr="", no_outer=False): typ = types[k] x = ser_one(v) if x is None: # TODO: optimize - if '__origin__' in typ.__dict__ and typ.__origin__ == collections.abc.Sequence: + #print('k', k, "typ",typ) + if typ == typing.Any and k == 'vendorExtensions': + if type(v) == ET.Element: + #print("v",v,type(v)) + xstr = ET.tostring(v, method='xml')#, encoding='utf8') + xstr = xstr.decode() + #print("xstr",xstr) + f.write(xstr) + else: + # uuuuuh idk fuck + f.write(repr(v)) + f.write('\n') + + elif typ == list or ('__origin__' in typ.__dict__ and typ.__origin__ in {collections.abc.Sequence,list}): if len(v) > 0: - f.write("<%s>\n" % k) + flatten = k in flattenchildren.get(T, ()) + if not flatten: f.write("<%s>\n" % k) ttt = typ.__args__[0] - isunion = '__origin__' in ttt.__dict__ and ttt.__origin__ == typing.Union + isdyn = ttt == typing.Any or ('__origin__' in ttt.__dict__ and ttt.__origin__ == typing.Union) for x in v: - if isunion: ttt = type(x) - gen_generic(f, x, ttt, type2tag[ttt], type2attr.get(ttt, ())) - f.write("\n" % k) + if isdyn: ttt = type(x) + #print("ttt",ttt) + gen_generic(f, x, ttt, type2tag[ttt], type2attr.get(ttt, ()), rec=[*rec, k]) + if not flatten: f.write("\n" % k) else: noouter = typ in {SvdDimElement, SvdRegisterProperties} - gen_generic(f, v, typ, k, type2attr.get(typ, ()), no_outer=noouter) + gen_generic(f, v, typ, k, type2attr.get(typ, ()), no_outer=noouter, rec=[*rec, k]) else: f.write("<%s>%s\n"%(k, x, k)) diff --git a/svd/svdparse.py b/svd/svdparse.py index 1ccdf6d..dd8bda3 100644 --- a/svd/svdparse.py +++ b/svd/svdparse.py @@ -192,6 +192,9 @@ def parse_registers(xd) -> Sequence[Union[SvdCluster, SvdRegister]]: def parse_peripheral(xd) -> SvdPeripheral: return parse_generic(xd, SvdPeripheral, 'peripheral', True, True, False, { 'registers': parse_registers, # FIXME + }, { + 'interrupt': parse_interrupt, + 'addressBlock': parse_addressBlock })