def parseIo(extention,device,path): outFile = open(posixpath.join(path,"Io.hpp"),'w',encoding='utf-8') outFile.write('#pragma once\n#include <Io/Io.hpp>\n#include <Register/Register.hpp>\n') outFile.write("namespace Kvasir{\n namespace Io{\n") io = Ft.getKey(extention,['kvasir','io']) for key in sorted(io): if key!="default": type = Ft.getKey(io,[key,'type']) if type == 'group': for port in formatIoPorts(Ft.getKey(io,[key,'ports'])): peripheral = Ft.getKey(io,[key,'peripheral']).replace('%s',port) register = Ft.getKey(io,[key,'register']).replace('%s',port) address = Ft.getKey(device,[peripheral]).base_address + Ft.getKey(device,[peripheral,register]).address_offset reserved = 0xFFFFFFFF for field in Ft.getKey(device,[peripheral,register]).fields: reserved = Ft.clearBitsFromRange(field.bit_offset + field.bit_width -1,field.bit_offset,reserved) portNumber = port if not portNumber.isdigit(): portNumber = ord(portNumber)-ord('A') if key == "read": action = "ReadAction" else: action = "WriteLiteralAction<(%s<<Pin)>" % Ft.getKey(io,[key,'value']) outFile.write(" template<int Pin>\n") outFile.write(" struct MakeAction<Action::%s,Register::PinLocation<%d,Pin>> :\n" % (key.capitalize(),portNumber)) outFile.write(" Register::Action<Register::FieldLocation<Register::Address<0x%08x,0x%08x>,(1<<Pin)>,Register::%s>{};\n\n"\ % (address,reserved,action)) outFile.write(" }\n}\n")
def parseIo(extention,device,path): outFile = open(os.path.join(path,"Io.hpp"),'w',encoding='utf-8') outFile.write('#pragma once\n#include "Io/Io.hpp"\n#include "Register/Register.hpp"\n') outFile.write("namespace Kvasir{\n namespace Io{\n") io = Ft.getKey(extention,['kvasir','io']) for key in sorted(io): if key!="default": type = Ft.getKey(io,[key,'type']) if type == 'group': for port in formatIoPorts(Ft.getKey(io,[key,'ports'])): peripheral = Ft.getKey(io,[key,'peripheral']).replace('%s',port) register = Ft.getKey(io,[key,'register']).replace('%s',port) address = Ft.getKey(device,[peripheral]).base_address + Ft.getKey(device,[peripheral,register]).address_offset reserved = 0xFFFFFFFF for field in Ft.getKey(device,[peripheral,register]).fields: reserved = Ft.clearBitsFromRange(field.bit_offset + field.bit_width -1,field.bit_offset,reserved) portNumber = port if not portNumber.isdigit(): portNumber = ord(portNumber)-ord('A') if key == "read": action = "ReadAction" else: action = "WriteLiteralAction<(%s<<Pin)>" % Ft.getKey(io,[key,'value']) outFile.write(" template<int Pin>\n") outFile.write(" struct MakeAction<Action::%s,PinLocation<%d,Pin>> :\n" % (key.capitalize(),portNumber)) outFile.write(" Register::Action<Register::BitLocation<Register::Address<0x%08x,0x%08x>,(1<<Pin)>,Register::%s>{};\n\n"\ % (address,reserved,action)) outFile.write(" }\n}\n")
def parseRegister(register, baseAddress, prefix, ext): noActionIfZeroBits = 0xFFFFFFFF noActionIfOneBits = 0x00000000 fieldOut = "" for field in register.fields: msb = field.bit_offset + field.bit_width - 1 lsb = field.bit_offset fieldType = "unsigned" fieldName = Ft.formatVariable(field.name) fieldOut += " ///%s\n" % Ft.formatComment(field.description) cValuesOut = "" if Ft.useEnumeratedValues(field.enumerated_values, field.bit_width): fieldType = "%sVal" % (fieldName.capitalize()) fieldOut += " enum class %s {\n" % fieldType cValuesOut = " namespace %sC{\n" % fieldType for v in field.enumerated_values: if v.value is not None and v.is_default is None: #some value are defaults, we ignore them valName = Ft.getKey( ext, ['field', field.name, 'enum', v.name, '.rename' ]) or Ft.formatEnumValue(v.name) if valName != 'reserved': fieldOut += " %s=0x%08x, ///<%s\n" % ( valName, v.value, Ft.formatComment(v.description)) cValuesOut += " constexpr Register::FieldValue<decltype(%s)::Type,%sVal::%s> %s{};\n" % ( fieldName, fieldName.capitalize(), valName, valName) fieldOut += " };\n" cValuesOut += " }\n" access = Ft.getAccess(field, Ft.getKey(ext, ['field', field.name])) fieldOut += " constexpr Register::FieldLocation<Addr,Register::maskFromRange(%d,%d),Register::%s,%s> %s{}; \n%s" % ( msb, lsb, access, fieldType, fieldName, cValuesOut) if "oneTo" not in access: #only remove bits from reserved field if a write of zero actually changes something noActionIfZeroBits = Ft.clearBitsFromRange(msb, lsb, noActionIfZeroBits) if "zeroTo" in access: #if zeroToSet or zeroToClear then writing a 1 is a no action noActionIfOneBits = Ft.setBitsFromRange(msb, lsb, noActionIfOneBits) regType = "std::uint32_t" if register.size is not None: if register.size is 8: regType = "std::uint8_t" elif register.size is 16: regType = "std::uint16_t" out = " namespace %s{ ///<%s\n" % (Ft.formatNamespace( "%s_%s" % (prefix, register.name)), Ft.formatComment(register.description)) out += " using Addr = Register::Address<0x%08x,0x%08x,0x%08x,%s>;\n" % ( baseAddress + register.address_offset, noActionIfZeroBits, noActionIfOneBits, regType) out += fieldOut out += " }\n" return out
def parseFile(company, file): print("Parsing %s,%s " % (company, file)) parser = SVDParser.for_packaged_svd(company, file + ".svd", 1) extention = [] jsonPath = posixpath.join(posixpath.dirname(posixpath.abspath(__file__)), "Extention", company, file + ".json") #print(jsonPath) device = parser.get_device() if posixpath.isfile(jsonPath): extFile = open(jsonPath, "r", encoding='utf-8') extention = json.load(extFile) subdir = Ft.formatCpuName(Ft.getKey(extention, ["device", "cpu", "name"]), device) chipDir = posixpath.join('..', '..', 'Lib', 'Chip') subdir = posixpath.join(chipDir, subdir) if not posixpath.exists(subdir): os.makedirs(subdir) subdir = posixpath.join(subdir, company) if not posixpath.exists(subdir): os.makedirs(subdir) subdir = posixpath.join(subdir, file) if not posixpath.exists(subdir): os.makedirs(subdir) chipText = "#pragma once \n" chipText += "#include <cstdint>\n" incDir = subdir[10:] if Ft.getKey(extention, ["kvasir", "io"]): parseIo(extention, device, subdir) chipText += "#include <%s>\n" % (posixpath.join(incDir, "Io.hpp")) for peripheral in device.peripherals: if peripheral.name is not None: chipText += "#include <%s>\n" % (posixpath.join( incDir, peripheral.name + ".hpp")) out = "#pragma once \n#include <Register/Utility.hpp>\n" out += "namespace Kvasir {\n" out += parsePeripheral( peripheral, Ft.getKey(extention, ['.' + peripheral.name])) out += "}\n" outFile = open(posixpath.join(subdir, peripheral.name + ".hpp"), 'w', encoding='utf-8') outFile.write(out) else: print("error no name in %s" % (file)) outFile = open(posixpath.join(chipDir, file + ".hpp"), 'w', encoding='utf-8') outFile.write(chipText)
def parsePeripheral(peripheral, ext): out = "" if peripheral.description is not None: out += "//%s\n" % (Ft.formatComment(peripheral.description)) out += parseRegisters(peripheral.registers, peripheral.base_address, peripheral.name, Ft.getKey(ext, ['register'])) return out
def parseRegister(register, baseAddress, prefix, ext): reservedBits = 0xFFFFFFFF fieldOut = "" for field in register.fields: msb = field.bit_offset+field.bit_width-1 lsb = field.bit_offset fieldType = "unsigned" fieldName = Ft.formatVariable(field.name) fieldOut += " ///%s\n" % field.description if Ft.useEnumeratedValues(field.enumerated_values,field.bit_width): fieldType = "%sVal" % (fieldName) fieldOut += " enum class %s {\n" % fieldType cValuesOut = "" for v in field.enumerated_values: if v.value is not None and v.is_default is None: #some value are defaults, we ignore them valName = Ft.getKey(ext,['field',field.name,'enum',v.name,'.rename']) or Ft.formatEnumValue(v.name) if valName != 'reserved': fieldOut+=" %s=0x%08x, ///<%s\n" % (valName,v.value,v.description) cValuesOut+=" constexpr MPL::Value<%sVal,%sVal::%s> %s{};\n" % (fieldName,fieldName,valName,valName) fieldOut += " };\n namespace %sValC{\n%s }\n" % (fieldName,cValuesOut) fieldOut += " constexpr Register::BitLocation<Addr,Register::maskFromRange(%d,%d),Register::%s,%s> %s{}; \n" % (msb,lsb,Ft.getAccess(register,field),fieldType,fieldName) reservedBits = Ft.clearBitsFromRange(msb,lsb,reservedBits) regType = "unsigned" if register.size is not None and register.size is 8: regType = "unsigned char" out = " namespace %s{ ///<%s\n" % (Ft.formatNamespace("%s%s" % (prefix, register.name)),register.description) out += " using Addr = Register::Address<0x%08x,0x%08x,0,%s>;\n" % (baseAddress + register.address_offset,reservedBits,regType) out += fieldOut out += " }\n" return out
def parseRegisters(registers,baseAddress,prefix, ext): if registers is None: return "" out = "" for register in registers: out += parseRegister(register, baseAddress, prefix, Ft.getKey(ext,[register.name])) return out
def parsePeripheral(peripheral, ext): out = "" if peripheral.description is not None: out += "//%s\n" % (Ft.formatComment(peripheral.description)) if peripheral.registers is not None: out += parseRegisters( peripheral.registers, peripheral.base_address, peripheral.name, Ft.getKey(ext, ["register"]) ) return out
def parseFile(company,file): print("Parsing %s,%s " % (company,file)) parser = SVDParser.for_packaged_svd(company, file + ".svd",1,1) extention = [] jsonPath = os.path.join(os.path.dirname(os.path.abspath(__file__)),"Extention",company,file+".json") #print(jsonPath) device = parser.get_device() if os.path.isfile(jsonPath): extFile = open(jsonPath,"r",encoding='utf-8') extention = json.load(extFile) subdir = Ft.formatCpuName(Ft.getKey(extention,["device","cpu","name"]),device) chipDir = os.path.join('..','..','Lib','Chip') subdir = os.path.join(chipDir, subdir) if not os.path.exists(subdir): os.makedirs(subdir) subdir = os.path.join(subdir,company) if not os.path.exists(subdir): os.makedirs(subdir) subdir = os.path.join(subdir,file) if not os.path.exists(subdir): os.makedirs(subdir) chipText = "#pragma once \n" incDir = subdir[10:] if Ft.getKey(extention,["kvasir","io"]): parseIo(extention,device,subdir) chipText += "#include \"%s\"\n" % (os.path.join(incDir,"Io.hpp")) for peripheral in device.peripherals: if peripheral.name is not None: chipText += "#include \"%s\"\n" % (os.path.join(incDir,peripheral.name+".hpp")) out = "#pragma once \n#include \"Register/Utility.hpp\"\n" out += "namespace Kvasir {\n" out += parsePeripheral(peripheral,Ft.getKey(extention,['.'+peripheral.name])) out += "}\n" outFile = open(os.path.join(subdir,peripheral.name+".hpp"), 'w',encoding='utf-8') outFile.write(out) else: print("error no name in %s" % (file)) outFile = open(os.path.join(chipDir,file + ".hpp"), 'w',encoding='utf-8') outFile.write(chipText)
def parseIo(extention, device, path): outFile = open(posixpath.join(path, "Io.hpp"), "w", encoding="utf-8") outFile.write("#pragma once\n#include <Io/Io.hpp>\n#include <Register/Register.hpp>\n") outFile.write("namespace Kvasir{\n namespace Io{\n") io = Ft.getKey(extention, ["kvasir", "io"]) for key in sorted(io): if key != "default": type = Ft.getKey(io, [key, "type"]) if type == "group": for port in formatIoPorts(Ft.getKey(io, [key, "ports"])): peripheral = Ft.getKey(io, [key, "peripheral"]).replace("%s", port) register = Ft.getKey(io, [key, "register"]).replace("%s", port) address = ( Ft.getKey(device, [peripheral]).base_address + Ft.getKey(device, [peripheral, register]).address_offset ) reserved = 0xFFFFFFFF for field in Ft.getKey(device, [peripheral, register]).fields: reserved = Ft.clearBitsFromRange( field.bit_offset + field.bit_width - 1, field.bit_offset, reserved ) portNumber = port if not portNumber.isdigit(): portNumber = ord(portNumber) - ord("A") if key == "read": action = "ReadAction" else: action = "WriteLiteralAction<(%s<<Pin)>" % Ft.getKey(io, [key, "value"]) outFile.write(" template<int Pin>\n") outFile.write( " struct MakeAction<Action::%s,Register::PinLocation<%d,Pin>> :\n" % (key.capitalize(), portNumber) ) outFile.write( " Register::Action<Register::FieldLocation<Register::Address<0x%08x,0x%08x>,(1<<Pin)>,Register::%s>{};\n\n" % (address, reserved, action) ) outFile.write(" }\n}\n")
def parsePeripheral(peripheral, ext): out = "//%s\n" % (peripheral.description) out += parseRegisters(peripheral.registers, peripheral.base_address, peripheral.prepend_to_name, Ft.getKey(ext,['register'])) return out
def parseRegister(register, baseAddress, prefix, ext): noActionIfZeroBits = 0xFFFFFFFF noActionIfOneBits = 0x00000000 fieldOut = "" for field in register.fields: msb = field.bit_offset + field.bit_width - 1 lsb = field.bit_offset fieldType = "unsigned" fieldName = Ft.formatVariable(field.name) fieldOut += " ///%s\n" % Ft.formatComment( Ft.getKey(ext, ["field", field.name, "description"]) or field.description ) cValuesOut = "" if Ft.useEnumeratedValues(field.enumerated_values, field.bit_width): fieldType = "%sVal" % (fieldName.capitalize()) fieldOut += " enum class %s {\n" % fieldType cValuesOut = " namespace %sC{\n" % fieldType for v in field.enumerated_values: if v.value is not None and v.is_default is None: # some value are defaults, we ignore them valName = Ft.getKey(ext, ["field", field.name, "enum", v.name, ".rename"]) or Ft.formatEnumValue( v.name ) if valName != "reserved": fieldOut += " %s=0x%08x, ///<%s\n" % ( valName, v.value, Ft.formatComment(v.description), ) cValuesOut += ( " constexpr Register::FieldValue<decltype(%s)::Type,%sVal::%s> %s{};\n" % (fieldName, fieldName.capitalize(), valName, valName) ) fieldOut += " };\n" cValuesOut += " }\n" access = Ft.getAccess(field, Ft.getKey(ext, ["field", field.name])) fieldOut += ( " constexpr Register::FieldLocation<Addr,Register::maskFromRange(%d,%d),Register::%s,%s> %s{}; \n%s" % (msb, lsb, access, fieldType, fieldName, cValuesOut) ) if "oneTo" not in access: # only remove bits from reserved field if a write of zero actually changes something noActionIfZeroBits = Ft.clearBitsFromRange(msb, lsb, noActionIfZeroBits) if "zeroTo" in access: # if zeroToSet or zeroToClear then writing a 1 is a no action noActionIfOneBits = Ft.setBitsFromRange(msb, lsb, noActionIfOneBits) size = Ft.getKey(ext, ["size"]) if size is not None: register.size = size elif register.size is None: register.size = 32 if register.size is 8: regType = "unsigned char" if register.size is 16: regType = "unsigned short" if register.size is 32: regType = "unsigned" out = " namespace %s{ ///<%s\n" % ( Ft.formatNamespace("%s_%s" % (prefix, register.name)), Ft.formatComment(register.description), ) out += " using Addr = Register::Address<0x%08x,0x%08x,0x%08x,%s>;\n" % ( baseAddress + register.address_offset, noActionIfZeroBits, noActionIfOneBits, regType, ) out += fieldOut out += " }\n" return out