Skip to content

Commit fb1a476

Browse files
deadprogramaykevl
authored andcommitted
generator: handle fields that use bitRange element and ensure all caps for attributes that are not already capitalized or start with number.
Also handle subclusters. Signed-off-by: Ron Evans <ron@hybridgroup.com>
1 parent 4397152 commit fb1a476

File tree

1 file changed

+59
-16
lines changed

1 file changed

+59
-16
lines changed

tools/gen-device-svd.py

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ def readSVD(path, sourceURL):
128128
peripheral['registers'].extend(parseRegister(groupName or name, register, baseAddress))
129129
for cluster in regsEls[0].findall('cluster'):
130130
clusterName = getText(cluster.find('name')).replace('[%s]', '')
131+
if cluster.find('dimIndex') is not None:
132+
clusterName = clusterName.replace('%s', '')
131133
clusterDescription = getText(cluster.find('description'))
132134
clusterPrefix = clusterName + '_'
133135
clusterOffset = int(getText(cluster.find('addressOffset')), 0)
@@ -137,6 +139,33 @@ def readSVD(path, sourceURL):
137139
cpRegisters = []
138140
for regEl in cluster.findall('register'):
139141
cpRegisters.extend(parseRegister(groupName, regEl, baseAddress, clusterName+"_"))
142+
# handle sub-clusters of registers
143+
for subClusterEl in cluster.findall('cluster'):
144+
subclusterName = getText(subClusterEl.find('name')).replace('[%s]', '')
145+
subclusterDescription = getText(subClusterEl.find('description'))
146+
subclusterPrefix = subclusterName + '_'
147+
subclusterOffset = int(getText(subClusterEl.find('addressOffset')), 0)
148+
subdim = int(getText(subClusterEl.find('dim')))
149+
subdimIncrement = int(getText(subClusterEl.find('dimIncrement')), 16)
150+
151+
if subdim > 1:
152+
subcpRegisters = []
153+
subregSize = 0
154+
for regEl in subClusterEl.findall('register'):
155+
subregSize += int(getText(regEl.find('size')))
156+
subcpRegisters.extend(parseRegister(groupName, regEl, baseAddress + subclusterOffset, subclusterPrefix))
157+
cpRegisters.append({
158+
'name': subclusterName,
159+
'address': baseAddress + subclusterOffset,
160+
'description': subclusterDescription,
161+
'registers': subcpRegisters,
162+
'array': subdim,
163+
'elementsize': subdimIncrement,
164+
})
165+
else:
166+
for regEl in subClusterEl.findall('register'):
167+
cpRegisters.extend(parseRegister(getText(regEl.find('name')), regEl, baseAddress + subclusterOffset, subclusterPrefix))
168+
140169
cpRegisters.sort(key=lambda r: r['address'])
141170
clusterPeripheral = {
142171
'name': name+ "_" +clusterName,
@@ -218,16 +247,25 @@ def parseBitfields(groupName, regName, fieldsEls, bitfieldPrefix=''):
218247
# names like 'CNT[31]'. Replace invalid characters with '_' when
219248
# needed.
220249
fieldName = cleanName(getText(fieldEl.find('name')))
221-
lsbTags = fieldEl.findall('lsb')
222-
if len(lsbTags) == 1:
223-
lsb = int(getText(lsbTags[0]))
224-
else:
250+
if not fieldName[0].isupper() and not fieldName[0].isdigit():
251+
fieldName = fieldName.upper()
252+
if len(fieldEl.findall('lsb')) == 1 and len(fieldEl.findall('msb')) == 1:
253+
# try to use lsb/msb tags
254+
lsb = int(getText(fieldEl.findall('lsb')[0]))
255+
msb = int(getText(fieldEl.findall('msb')[0]))
256+
elif len(fieldEl.findall('bitOffset')) > 0 and len(fieldEl.findall('bitWidth')) > 0:
257+
# try to use bitOffset/bitWidth tags
225258
lsb = int(getText(fieldEl.find('bitOffset')))
226-
msbTags = fieldEl.findall('msb')
227-
if len(msbTags) == 1:
228-
msb = int(getText(msbTags[0]))
229-
else:
230259
msb = int(getText(fieldEl.find('bitWidth'))) + lsb - 1
260+
elif len(fieldEl.findall('bitRange')) > 0:
261+
# try use bitRange
262+
bitRangeTags = fieldEl.findall('bitRange')
263+
lsb = int(getText(bitRangeTags[0]).split(":")[1][:-1])
264+
msb = int(getText(bitRangeTags[0]).split(":")[0][1:])
265+
else:
266+
# this is an error. what to do?
267+
print("unable to find lsb/msb in field:", fieldName)
268+
231269
fields.append({
232270
'name': '{}_{}{}_{}_Pos'.format(groupName, bitfieldPrefix, regName, fieldName),
233271
'description': 'Position of %s field.' % fieldName,
@@ -246,6 +284,8 @@ def parseBitfields(groupName, regName, fieldsEls, bitfieldPrefix=''):
246284
})
247285
for enumEl in fieldEl.findall('enumeratedValues/enumeratedValue'):
248286
enumName = getText(enumEl.find('name'))
287+
if not enumName[0].isupper() and not enumName[0].isdigit():
288+
enumName = enumName.upper()
249289
enumDescription = getText(enumEl.find('description')).replace('\n', ' ')
250290
enumValue = int(getText(enumEl.find('value')), 0)
251291
fields.append({
@@ -311,15 +351,17 @@ def parseRegister(groupName, regEl, baseAddress, bitfieldPrefix=''):
311351
'elementsize': reg.size(),
312352
})
313353
# set first result bitfield
314-
shortName = reg.name().replace('_%s', '').replace('%s', '')
354+
shortName = reg.name().replace('_%s', '').replace('%s', '').upper()
315355
results[0]['bitfields'] = parseBitfields(groupName, shortName, fieldsEls, bitfieldPrefix)
316356
return results
317-
357+
regName = reg.name()
358+
if not regName[0].isupper() and not regName[0].isdigit():
359+
regName = regName.upper()
318360
return [{
319-
'name': reg.name(),
361+
'name': regName,
320362
'address': reg.address(),
321363
'description': reg.description(),
322-
'bitfields': parseBitfields(groupName, reg.name(), fieldsEls, bitfieldPrefix),
364+
'bitfields': parseBitfields(groupName, regName, fieldsEls, bitfieldPrefix),
323365
'array': reg.dim(),
324366
'elementsize': reg.size(),
325367
}]
@@ -417,7 +459,7 @@ def writeGo(outdir, device):
417459
subregType = 'volatile.Register32'
418460
elif subregister['elementsize'] == 2:
419461
subregType = 'volatile.Register16'
420-
else:
462+
elif subregister['elementsize'] == 1:
421463
subregType = 'volatile.Register8'
422464

423465
if subregister['array']:
@@ -439,13 +481,14 @@ def writeGo(outdir, device):
439481
padNumber += 1
440482
subaddress += bytesNeeded
441483
if subregister['array'] is not None:
442-
subaddress += subregister['elementsize'] * subregister['array']
484+
subregSize = subregister['array'] * subregister['elementsize']
443485
else:
444-
subaddress += subregister['elementsize']
486+
subregSize = subregister['elementsize']
487+
subaddress += subregSize
445488
regType += '\t\t{name} {subregType}\n'.format(name=subregister['name'], subregType=subregType)
446489
if register['array'] is not None:
447490
if subaddress != register['address'] + register['elementsize']:
448-
numSkip = ((register['address'] + register['elementsize']) - subaddress) // 4
491+
numSkip = ((register['address'] + register['elementsize']) - subaddress) // subregSize
449492
if numSkip <= 1:
450493
regType += '\t\t_padding{padNumber} {subregType}\n'.format(padNumber=padNumber, subregType=subregType)
451494
else:

0 commit comments

Comments
 (0)