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 type(v) == tuple: return "r%dp%d" % (v[0], v[1]) else: return None type2attr = { SvdSauRegion: {'enabled','name'}, SvdSauRegionsConfig: {'enabled','protectionWhenDisabled'}, SvdEnumeratedValues: {'derivedFrom'}, SvdCluster: {'derivedFrom'}, SvdField: {'derivedFrom'}, SvdRegister: {'derivedFrom'}, SvdPeripheral: {'derivedFrom'}, } type2tag = { SvdSauRegion: 'region', SvdSauRegionsConfig: 'sauRegionsConfig', SvdCpu: 'cpu', SvdRegisterProperties: 'registerProperties', SvdEnumeratedValue: 'enumeratedValue', SvdEnumeratedValues: 'enumeratedValues', SvdDimArrayIndex: 'dimArrayIndex', SvdDimElement: 'dimElement', SvdAddressBlock: 'addressBlock', SvdInterrupt: 'interrupt', SvdCluster: 'cluster', SvdWriteConstraintRange: 'range', SvdWriteConstraint: 'writeConstraint', SvdField: 'field', SvdRegister: 'register', SvdPeripheral: 'peripheral', SvdDevice: 'device', } def gen_generic(f, svdelem, T, tag, attrs=(), extraattr="", no_outer=False): atdict={} childdict={} d = dict((n, svdelem.__getattribute__(n)) for n in T._fields) for k, v in d.items(): if v is None: continue if k in attrs: atdict[k] = v else: childdict[k] = v atstr = ' '.join('%s="%s"' % (k, ser_one(v)) for k, v in atdict.items()) if not no_outer: f.write("<%s%s%s%s>\n" % (tag, (' ' if len(atstr)+len(extraattr)>0 else ''), atstr, extraattr)) types = get_type_hints(T) for k, v in childdict.items(): if v is None: continue typ = types[k] x = ser_one(v) if x is None: # TODO: optimize if '__origin__' in typ.__dict__ and typ.__origin__ == collections.abc.Sequence: if len(v) > 0: f.write("<%s>\n" % k) ttt = typ.__args__[0] isunion = '__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) else: noouter = typ in {SvdDimElement, SvdRegisterProperties} gen_generic(f, v, typ, k, type2attr.get(typ, ()), no_outer=noouter) else: f.write("<%s>%s\n"%(k, x, k)) if not no_outer: f.write("\n" % tag) def generate(f, dev: SvdDevice): f.write("""\n""") gen_generic(f, dev, SvdDevice, 'device', extraattr=""" schemaVersion="1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="CMSIS-SVD.xsd" """)