fix svd parser & generator stuff
This commit is contained in:
parent
4a9db32d33
commit
bab3f7141f
15
svd/svd.py
15
svd/svd.py
|
@ -176,8 +176,8 @@ class SvdPeripheral(NamedTuple):
|
||||||
disableCondition: str
|
disableCondition: str
|
||||||
baseAddress: int
|
baseAddress: int
|
||||||
registerProperties: SvdRegisterProperties
|
registerProperties: SvdRegisterProperties
|
||||||
addressBlock: SvdAddressBlock
|
addressBlock: Sequence[SvdAddressBlock]
|
||||||
interrupt: SvdInterrupt
|
interrupt: Sequence[SvdInterrupt]
|
||||||
registers: Sequence[Union[SvdRegister, SvdCluster]]
|
registers: Sequence[Union[SvdRegister, SvdCluster]]
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,5 +198,16 @@ class SvdDevice(NamedTuple):
|
||||||
peripherals: Sequence[SvdPeripheral]
|
peripherals: Sequence[SvdPeripheral]
|
||||||
vendorExtensions: Any
|
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?
|
# TODO: functions for expanding/flattening registerProperties, dimElements and derivedFrom?
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
|
|
||||||
|
import xml, xml.etree
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
import typing, collections.abc
|
import typing, collections.abc
|
||||||
|
|
||||||
from svd import *
|
from svd import *
|
||||||
from typing import get_type_hints
|
from typing import get_type_hints
|
||||||
|
|
||||||
|
|
||||||
# FIXME:
|
|
||||||
# * peripheral registers not emitting
|
|
||||||
|
|
||||||
|
|
||||||
def ser_one(v) -> str:
|
def ser_one(v) -> str:
|
||||||
assert v is not None
|
assert v is not None
|
||||||
if isinstance(v, bool): return "true" if v else "false"
|
if isinstance(v, bool): return "true" if v else "false"
|
||||||
elif isinstance(v, int): return hex(v)
|
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:
|
elif type(v) == tuple:
|
||||||
return "r%dp%d" % (v[0], v[1])
|
return "r%dp%d" % (v[0], v[1])
|
||||||
else: return None
|
else: return None
|
||||||
|
@ -47,9 +46,17 @@ type2tag = {
|
||||||
SvdPeripheral: 'peripheral',
|
SvdPeripheral: 'peripheral',
|
||||||
SvdDevice: 'device',
|
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={}
|
atdict={}
|
||||||
childdict={}
|
childdict={}
|
||||||
|
|
||||||
|
@ -71,18 +78,33 @@ def gen_generic(f, svdelem, T, tag, attrs=(), extraattr="", no_outer=False):
|
||||||
typ = types[k]
|
typ = types[k]
|
||||||
x = ser_one(v)
|
x = ser_one(v)
|
||||||
if x is None: # TODO: optimize
|
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:
|
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]
|
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:
|
for x in v:
|
||||||
if isunion: ttt = type(x)
|
if isdyn: ttt = type(x)
|
||||||
gen_generic(f, x, ttt, type2tag[ttt], type2attr.get(ttt, ()))
|
#print("ttt",ttt)
|
||||||
f.write("</%s>\n" % k)
|
gen_generic(f, x, ttt, type2tag[ttt], type2attr.get(ttt, ()), rec=[*rec, k])
|
||||||
|
if not flatten: f.write("</%s>\n" % k)
|
||||||
else:
|
else:
|
||||||
noouter = typ in {SvdDimElement, SvdRegisterProperties}
|
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:
|
else:
|
||||||
f.write("<%s>%s</%s>\n"%(k, x, k))
|
f.write("<%s>%s</%s>\n"%(k, x, k))
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,9 @@ def parse_registers(xd) -> Sequence[Union[SvdCluster, SvdRegister]]:
|
||||||
def parse_peripheral(xd) -> SvdPeripheral:
|
def parse_peripheral(xd) -> SvdPeripheral:
|
||||||
return parse_generic(xd, SvdPeripheral, 'peripheral', True, True, False, {
|
return parse_generic(xd, SvdPeripheral, 'peripheral', True, True, False, {
|
||||||
'registers': parse_registers, # FIXME
|
'registers': parse_registers, # FIXME
|
||||||
|
}, {
|
||||||
|
'interrupt': parse_interrupt,
|
||||||
|
'addressBlock': parse_addressBlock
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue