import io import sys import xml.etree.ElementTree as ET import math def sortchildrenby(parent, attr): parent[:] = sorted(parent, key=lambda child: int(child.find(attr).text, 16)) # Print usage information if len(sys.argv) != 2: print(f"Usage: {sys.argv[0]} ") exit() # Parse SVD file svd = ET.parse(sys.argv[1]).getroot() # Read processor information processor_name = svd.find("name").text register_width = svd.find("width").text register_type = f"u{register_width}" code = "" # Add header code += f"// MMIO Register definition for {processor_name}\n\n" # Add type definition for register type of correct size code += f"using reg_t = {register_type};\n\n\n" for peripheral in svd.find("peripherals"): derived = peripheral.attrib.get("derivedFrom") peripheral_name = peripheral.find("name").text peripheral_address = int(peripheral.find("baseAddress").text, 16) # Generate struct header code += f"struct {peripheral_name}_t" # If register definition has been derived from somewhere else, derive the struct from the other struct if derived != None: code += f" : {derived}_t" code += " {\n" prev_offset = 0 registers = peripheral.find("registers") if registers != None: sortchildrenby(registers, "addressOffset") for register in registers: register_name = register.find("name").text register_offset = int(register.find("addressOffset").text, 16) # Check if padding has to be inserted if prev_offset == 0: pass elif register_offset - prev_offset > 4: code += f" padding[{register_offset - prev_offset - 4}];\n" elif (register_offset - prev_offset != 0) and (register_offset - prev_offset != 4): print(f"Overlapping register {register_name}!") exit() # Add register variable declaration code += f" reg_t {register_name}; // 0x{register_offset:03X}\n" prev_offset = register_offset code += "};\n" # Place instance of register type in memory code += f"{peripheral_name}_t {peripheral_name} @ 0x{peripheral_address:08X};\n\n" # Write generated code to a file with open(sys.argv[1] + ".pat", "w") as file: file.write(code)