from typing import * class Diff(NamedTuple): fullname: str values: Tuple[Any,Any] SvdEndian = Literal["little", "big", "selectable", "other"] SvdSauAccess = Literal["n", "c", "s"] SvdProtection = Literal["s", "n", "p"] SvdAddressUsage = Literal["registers", "buffer", "reserved"] SvdUsage = Literal["read", "write", "read-write"] SvdDataType = Literal[ "uint8_t","uint16_t","uint32_t","uint64_t", "int8_t","int16_t","int32_t","int64_t", "uint8_t*","uint16_t*","uint32_t*","uint64_t*", "int8_t*","int16_t*","int32_t*","int64_t*" ] SvdModifiedWriteValues = Literal[ "oneToClear", "oneToSet", "oneToToggle", "zeroToSet", "zeroToClear", "zeroToToggle", "clear", "set", "modify" ] SvdReadAction = Literal["clear", "set", "modify", "modifyExternal"] SvdAccess = Literal["read-only", "write-only", "read-write", "writeOnce", "read-writeOnce"] def diff_base(a, b, base, T, names): for n in names: av = a.__getattribute__(n) bv = b.__getattribute__(n) if av != bv: yield Diff("%s.%s"%(base,n),(av,bv)) def diff_structmemb(a, b, base, T, name): av = a.__getattribute__(name) bv = b.__getattribute__(name) if av is None and bv is None: pass elif (av is None and bv is not None) or (av is not None and bv is None): yield Diff("%s.%s"%(base,name),(av,bv)) else: yield from av.__diff__(bv, "%s.%s"%(base,name)) def diff_structseq(a, b, base, T, name): av = a.__getattribute__(name) bv = b.__getattribute__(name) if av is None and bv is None: pass elif (av is None and bv is not None) or (av is not None and bv is None): yield Diff("%s.%s"%(base,name),(av,bv)) elif len(av) != len(bv): yield Diff("%s.%s#"%(base,name), (len(av), len(bv))) else: for i in range(len(av)): yield from av[i].__diff__(bv[i], "%s.%s[%d]"%(base,name,i)) class SvdSauRegion(NamedTuple): enabled: bool = None # attribute name: str = None # attribute base: int = None limit: int = None access: SvdSauAccess = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdSauRegion, ['enabled','name','base','limit','access']) class SvdSauRegionsConfig(NamedTuple): enabled: bool # attribute protectionWhenDisabled: SvdSauAccess # attribute regions: Sequence[SvdSauRegion] def __diff__(self, other, base): yield from diff_base(self, other, base, SvdSauRegionsConfig, ['enabled','protectionWhenDisabled']) yield from diff_structseq(self, other, base, SvdSauRegionsConfig, 'regions') class SvdCpu(NamedTuple): name: str # explicitly not restricting to standard CMSIS names, because we'll be doing non-ARM stuff anyway revision: Tuple[int, int] = None endian: SvdEndian = None mpuPresent: bool = None fpuPresent: bool = None fpuDP: bool = None dspPresent: bool = None icachePresent: bool = None dcachePresent: bool = None itcmPresent: bool = None dtcmPresent: bool = None vtorPresent: bool = None nvicPrioBits: int = None vendorSystickConfig: bool = None deviceNumInterrupts: int = None sauNumRegions: int = None sauRegionsConfig: SvdSauRegionsConfig = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdCpu, ['name','revision','endian','mpuPresent','fpuPresent','fpuDP', 'dspPresent','icachePresent','dcachePresent','itcmPresent', 'dtcmPresent','vtorPresent','nvicPrioBits','vendorSystickConfig', 'deviceNumInterrupts','sauNumRegions']) yield from diff_structmemb(self, other, base, SvdCpu, 'sauRegionsConfig') class SvdRegisterProperties(NamedTuple): size: int = None access: SvdAccess = None protection: SvdProtection = None resetValue: int = None resetMask: int = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdRegisterProperties, ['size','access','protection','resetValue','resetMask']) class SvdEnumeratedValue(NamedTuple): name: str = None description: str = None value: int = None isDefault: bool = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdEnumeratedValue, ['name','description','value','isDefault']) class SvdEnumeratedValues(NamedTuple): derivedFrom: str = None # attribute name: str = None usage: SvdUsage = None enumeratedValue: Sequence[SvdEnumeratedValue] = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdEnumeratedValues, ['derivedFrom','name','usage']) yield from diff_structseq(self, other, base, SvdEnumeratedValues, 'enumeratedValue') class SvdDimArrayIndex(NamedTuple): headerEnumName: str = None enumeratedValue: SvdEnumeratedValue = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdDimArrayIndex, ['headerEnumName','enumeratedValue']) class SvdDimElement(NamedTuple): dim: int = None dimIncrement: int = None dimIndex: str = None dimName: str = None dimArrayIndex: SvdDimArrayIndex = None headerEnumName: str = None enumeratedValue: SvdEnumeratedValue = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdDimElement, ['dim','dimIncrement','dimIndex','dimName','headerEnumName']) yield from diff_structmemb(self, other, base, SvdDimElement, 'dimArrayIndex') yield from diff_structmemb(self, other, base, SvdDimElement, 'enumeratedValue') class SvdAddressBlock(NamedTuple): offset: int = None size: int = None usage: SvdAddressUsage = None protection: SvdProtection = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdAddressBlock, ['offset','size','usage','protection']) class SvdInterrupt(NamedTuple): name: str = None description: str = None value: int = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdInterrupt, ['name','description','value']) class SvdCluster(NamedTuple): derivedFrom: str = None # attribute dimElement: SvdDimElement = None name: str = None description: str = None alternateCluster: str = None headerStructName: str = None addressOffset: int = None registerProperties: SvdRegisterProperties = None register: Sequence[Any] = None cluster: Sequence[Any] = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdCluster, ['name','description','value']) yield from diff_structmemb(self, other, base, SvdCluster, 'registerProperties') yield from diff_structseq(self, other, base, SvdCluster, 'register') yield from diff_structseq(self, other, base, SvdCluster, 'cluster') class SvdWriteConstraintRange(NamedTuple): minimum: int = None maximum: int = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdWriteConstraintRange, ['minimum','maximum']) class SvdWriteConstraint(NamedTuple): writeAsRead: bool = None useEnumeratedValues: bool = None range: SvdWriteConstraintRange = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdWriteConstraint, ['writeAsRead','useEnumeratedValues']) yield from diff_structmemb(self, other, base, SvdWriteConstraint, 'range') class SvdField(NamedTuple): derivedFrom: str = None # attribute dimElement: SvdDimElement = None name: str = None description: str = None bitOffset: int = None bitWidth: int = None lsb: int = None msb: int = None bitRange: str = None access: SvdAccess = None modifiedWriteValues: SvdModifiedWriteValues = None writeConstraint: SvdWriteConstraint = None readAction: SvdReadAction = None enumeratedValues: SvdEnumeratedValues = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdField, ['derivedFrom','name','description','bitOffset','bitWidth','lsb', 'msb','bitRange','access','modifiedWriteValues','readAction']) yield from diff_structmemb(self, other, base, SvdField, 'dimElement') yield from diff_structmemb(self, other, base, SvdField, 'writeConstraint') yield from diff_structmemb(self, other, base, SvdField, 'enumeratedValues') class SvdRegister(NamedTuple): derivedFrom: str = None # attribute dimElement: SvdDimElement = None name: str = None displayName: str = None description: str = None alternateGroup: str = None alternateRegister: str = None addressOffset: int = None registerProperties: SvdRegisterProperties = None dataType: SvdDataType = None modifiedWriteValues: SvdModifiedWriteValues = None writeConstraint: SvdWriteConstraint = None readAction: SvdReadAction = None fields: Sequence[SvdField] = None # ignoring for now because this SVD is VERY broken #enumeratedValues: SvdEnumeratedValues # HACK: SiFive e310x, Kendryte k210 def __diff__(self, other, base): yield from diff_base(self, other, base, SvdRegister, ['derivedFrom','name','displayName','description','alternateGroup', 'alternateRegister','addressOffset','dataType','modifiedWriteValues', 'readAction']) yield from diff_structmemb(self, other, base, SvdRegister, 'dimElement') yield from diff_structmemb(self, other, base, SvdRegister, 'registerProperties') yield from diff_structmemb(self, other, base, SvdRegister, 'writeConstraint') yield from diff_structseq(self, other, base, SvdRegister, 'fields') class SvdPeripheral(NamedTuple): derivedFrom: str = None # attribute name: str = None version: str = None description: str = None alternatePeripheral: str = None groupName: str = None prependToName: str = None appendToName: str = None headerStructName: str = None disableCondition: str = None baseAddress: int = None registerProperties: SvdRegisterProperties = None addressBlock: Sequence[SvdAddressBlock] = None interrupt: Sequence[SvdInterrupt] = None registers: Sequence[Union[SvdRegister, SvdCluster]] = None def __diff__(self, other, base): yield from diff_base(self, other, base, SvdPeripheral, ['derivedFrom','name','version','description','alternatePeripheral', 'groupName','prependToName','appendToName','headerStructName', 'disableCondition','baseAddress']) yield from diff_structmemb(self, other, base, SvdPeripheral, 'registerProperties') yield from diff_structseq(self, other, base, SvdPeripheral, 'addressBlock') yield from diff_structseq(self, other, base, SvdPeripheral, 'interrupt') yield from diff_structseq(self, other, base, SvdPeripheral, 'registers') class SvdDevice(NamedTuple): vendor: str vendorID: str name: str series: str = None version: str = None description: str = None licenseText: str = None cpu: SvdCpu = None headerSystemFilename: str = None headerDefinitionsPrefix: str = None addressUnitBits: int = None width: int = None registerProperties: SvdRegisterProperties = None peripherals: Sequence[SvdPeripheral] = None vendorExtensions: Any = None 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 # ignore vendorExtensions def __diff__(self, other, base='device'): yield from diff_base(self, other, base, SvdDevice, ['vendor','vendorID','name','series','version','description', 'licenseText','headerSystemFilename','headerDefinitionsPrefix', 'addressUnitBits','width']) yield from diff_structmemb(self, other, base, SvdDevice, 'cpu') yield from diff_structmemb(self, other, base, SvdDevice, 'registerProperties') yield from diff_structseq(self, other, base, SvdDevice, 'peripherals') # TODO: functions for expanding/flattening registerProperties, dimElements and derivedFrom?