mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-12-19 00:11:30 +01:00
Since turning from old build flow. New Altera SoCFPGA requires converting handsoff conversion via the python script. This is from official provided, and now sync to U-Boot with better location at tools/cv_xxxx. Meantime, requirement.txt is also provided to further explain the libraries require for these scripts. Signed-off-by: Brian Sune <briansune@gmail.com> Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
572 lines
20 KiB
Python
Executable File
572 lines
20 KiB
Python
Executable File
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
|
"""
|
|
Pinmux header file generator
|
|
|
|
Process the hps.xml from Quartus and convert them to headers
|
|
usable by U-Boot.
|
|
|
|
Copyright (C) 2022 Intel Corporation <www.intel.com>
|
|
|
|
Author: Lee, Kah Jing <kah.jing.lee@intel.com>
|
|
"""
|
|
import os
|
|
import re
|
|
import streamer
|
|
import xmlgrok
|
|
import xml.dom.minidom
|
|
import collections
|
|
import io
|
|
from io import StringIO
|
|
|
|
class CompatStringIO(io.StringIO):
|
|
def write(self, s):
|
|
if hasattr(s, 'decode'):
|
|
# Use unicode for python2 to keep compatible
|
|
return int(super(CompatStringIO, self).write(s.decode('utf-8')))
|
|
else:
|
|
return super(CompatStringIO, self).write(s)
|
|
def getvalue(self):
|
|
return str(super(CompatStringIO, self).getvalue())
|
|
|
|
class HPSGrokker(object):
|
|
|
|
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
|
|
TEMPLATE_DIR = os.path.dirname(SCRIPT_DIR) + '/src'
|
|
|
|
MAKEFILE_FILENAME = "Makefile"
|
|
makefileTemplate = ""
|
|
RESET_CONFIG_H_FILENAME = "reset_config.h"
|
|
resetConfigHTemplate = ""
|
|
|
|
# If no device family is specified, assume Cyclone V.
|
|
derivedDeviceFamily = "cyclone5"
|
|
|
|
# Assume FPGA DMA 0-7 are not in use by default
|
|
# Note: there appears to be a weird mismatch between sopcinfo
|
|
# value vs hps.xml value of DMA_Enable of string_list hw.tcl
|
|
# type, where sopcinfo uses comma as separator e.g.
|
|
# "No,No,No,..." while hps.xml uses space as separator.
|
|
dmaEnable = "No No No No No No No No"
|
|
|
|
def __init__(self, inputDir, outputDir, hpsFileName='hps.xml'):
|
|
""" HPSGrokker initialization """
|
|
self.inputDir = inputDir
|
|
self.outputDir = outputDir
|
|
self.hpsInFileName = inputDir + os.sep + hpsFileName
|
|
self.dom = xml.dom.minidom.parse(self.hpsInFileName)
|
|
self.peripheralStream = None
|
|
self.pinmuxConfigBuffer = None
|
|
self.pinmuxHeaderBuffer = None
|
|
self.pinmuxHeaderFile = None
|
|
self.pinmuxArraySize = 0
|
|
self.config_hps_ = "CFG_HPS_"
|
|
self.clockStream = None
|
|
self.pinmux_regs = self.get_default_pinmux_regs()
|
|
self.pinmux_configs = self.get_default_pinmux_configs()
|
|
self.pinmux_config_h = None
|
|
|
|
self.createFilesFromHPS()
|
|
|
|
def get_default_pinmux_regs(self):
|
|
""" Set default pinmux values """
|
|
p = collections.OrderedDict()
|
|
|
|
p['EMACIO0'] = 0
|
|
p['EMACIO1'] = 0
|
|
p['EMACIO2'] = 0
|
|
p['EMACIO3'] = 0
|
|
p['EMACIO4'] = 0
|
|
p['EMACIO5'] = 0
|
|
p['EMACIO6'] = 0
|
|
p['EMACIO7'] = 0
|
|
p['EMACIO8'] = 0
|
|
p['EMACIO9'] = 0
|
|
p['EMACIO10'] = 0
|
|
p['EMACIO11'] = 0
|
|
p['EMACIO12'] = 0
|
|
p['EMACIO13'] = 0
|
|
p['EMACIO14'] = 0
|
|
p['EMACIO15'] = 0
|
|
p['EMACIO16'] = 0
|
|
p['EMACIO17'] = 0
|
|
p['EMACIO18'] = 0
|
|
p['EMACIO19'] = 0
|
|
p['FLASHIO0'] = 0
|
|
p['FLASHIO1'] = 0
|
|
p['FLASHIO2'] = 0
|
|
p['FLASHIO3'] = 0
|
|
p['FLASHIO4'] = 0
|
|
p['FLASHIO5'] = 0
|
|
p['FLASHIO6'] = 0
|
|
p['FLASHIO7'] = 0
|
|
p['FLASHIO8'] = 0
|
|
p['FLASHIO9'] = 0
|
|
p['FLASHIO10'] = 0
|
|
p['FLASHIO11'] = 0
|
|
p['GENERALIO0'] = 0
|
|
p['GENERALIO1'] = 0
|
|
p['GENERALIO2'] = 0
|
|
p['GENERALIO3'] = 0
|
|
p['GENERALIO4'] = 0
|
|
p['GENERALIO5'] = 0
|
|
p['GENERALIO6'] = 0
|
|
p['GENERALIO7'] = 0
|
|
p['GENERALIO8'] = 0
|
|
p['GENERALIO9'] = 0
|
|
p['GENERALIO10'] = 0
|
|
p['GENERALIO11'] = 0
|
|
p['GENERALIO12'] = 0
|
|
p['GENERALIO13'] = 0
|
|
p['GENERALIO14'] = 0
|
|
p['GENERALIO15'] = 0
|
|
p['GENERALIO16'] = 0
|
|
p['GENERALIO17'] = 0
|
|
p['GENERALIO18'] = 0
|
|
p['GENERALIO19'] = 0
|
|
p['GENERALIO20'] = 0
|
|
p['GENERALIO21'] = 0
|
|
p['GENERALIO22'] = 0
|
|
p['GENERALIO23'] = 0
|
|
p['GENERALIO24'] = 0
|
|
p['GENERALIO25'] = 0
|
|
p['GENERALIO26'] = 0
|
|
p['GENERALIO27'] = 0
|
|
p['GENERALIO28'] = 0
|
|
p['GENERALIO29'] = 0
|
|
p['GENERALIO30'] = 0
|
|
p['GENERALIO31'] = 0
|
|
p['MIXED1IO0'] = 0
|
|
p['MIXED1IO1'] = 0
|
|
p['MIXED1IO2'] = 0
|
|
p['MIXED1IO3'] = 0
|
|
p['MIXED1IO4'] = 0
|
|
p['MIXED1IO5'] = 0
|
|
p['MIXED1IO6'] = 0
|
|
p['MIXED1IO7'] = 0
|
|
p['MIXED1IO8'] = 0
|
|
p['MIXED1IO9'] = 0
|
|
p['MIXED1IO10'] = 0
|
|
p['MIXED1IO11'] = 0
|
|
p['MIXED1IO12'] = 0
|
|
p['MIXED1IO13'] = 0
|
|
p['MIXED1IO14'] = 0
|
|
p['MIXED1IO15'] = 0
|
|
p['MIXED1IO16'] = 0
|
|
p['MIXED1IO17'] = 0
|
|
p['MIXED1IO18'] = 0
|
|
p['MIXED1IO19'] = 0
|
|
p['MIXED1IO20'] = 0
|
|
p['MIXED1IO21'] = 0
|
|
p['MIXED2IO0'] = 0
|
|
p['MIXED2IO1'] = 0
|
|
p['MIXED2IO2'] = 0
|
|
p['MIXED2IO3'] = 0
|
|
p['MIXED2IO4'] = 0
|
|
p['MIXED2IO5'] = 0
|
|
p['MIXED2IO6'] = 0
|
|
p['MIXED2IO7'] = 0
|
|
p['GPLINMUX48'] = 0
|
|
p['GPLINMUX49'] = 0
|
|
p['GPLINMUX50'] = 0
|
|
p['GPLINMUX51'] = 0
|
|
p['GPLINMUX52'] = 0
|
|
p['GPLINMUX53'] = 0
|
|
p['GPLINMUX54'] = 0
|
|
p['GPLINMUX55'] = 0
|
|
p['GPLINMUX56'] = 0
|
|
p['GPLINMUX57'] = 0
|
|
p['GPLINMUX58'] = 0
|
|
p['GPLINMUX59'] = 0
|
|
p['GPLINMUX60'] = 0
|
|
p['GPLINMUX61'] = 0
|
|
p['GPLINMUX62'] = 0
|
|
p['GPLINMUX63'] = 0
|
|
p['GPLINMUX64'] = 0
|
|
p['GPLINMUX65'] = 0
|
|
p['GPLINMUX66'] = 0
|
|
p['GPLINMUX67'] = 0
|
|
p['GPLINMUX68'] = 0
|
|
p['GPLINMUX69'] = 0
|
|
p['GPLINMUX70'] = 0
|
|
p['GPLMUX0'] = 1
|
|
p['GPLMUX1'] = 1
|
|
p['GPLMUX2'] = 1
|
|
p['GPLMUX3'] = 1
|
|
p['GPLMUX4'] = 1
|
|
p['GPLMUX5'] = 1
|
|
p['GPLMUX6'] = 1
|
|
p['GPLMUX7'] = 1
|
|
p['GPLMUX8'] = 1
|
|
p['GPLMUX9'] = 1
|
|
p['GPLMUX10'] = 1
|
|
p['GPLMUX11'] = 1
|
|
p['GPLMUX12'] = 1
|
|
p['GPLMUX13'] = 1
|
|
p['GPLMUX14'] = 1
|
|
p['GPLMUX15'] = 1
|
|
p['GPLMUX16'] = 1
|
|
p['GPLMUX17'] = 1
|
|
p['GPLMUX18'] = 1
|
|
p['GPLMUX19'] = 1
|
|
p['GPLMUX20'] = 1
|
|
p['GPLMUX21'] = 1
|
|
p['GPLMUX22'] = 1
|
|
p['GPLMUX23'] = 1
|
|
p['GPLMUX24'] = 1
|
|
p['GPLMUX25'] = 1
|
|
p['GPLMUX26'] = 1
|
|
p['GPLMUX27'] = 1
|
|
p['GPLMUX28'] = 1
|
|
p['GPLMUX29'] = 1
|
|
p['GPLMUX30'] = 1
|
|
p['GPLMUX31'] = 1
|
|
p['GPLMUX32'] = 1
|
|
p['GPLMUX33'] = 1
|
|
p['GPLMUX34'] = 1
|
|
p['GPLMUX35'] = 1
|
|
p['GPLMUX36'] = 1
|
|
p['GPLMUX37'] = 1
|
|
p['GPLMUX38'] = 1
|
|
p['GPLMUX39'] = 1
|
|
p['GPLMUX40'] = 1
|
|
p['GPLMUX41'] = 1
|
|
p['GPLMUX42'] = 1
|
|
p['GPLMUX43'] = 1
|
|
p['GPLMUX44'] = 1
|
|
p['GPLMUX45'] = 1
|
|
p['GPLMUX46'] = 1
|
|
p['GPLMUX47'] = 1
|
|
p['GPLMUX48'] = 1
|
|
p['GPLMUX49'] = 1
|
|
p['GPLMUX50'] = 1
|
|
p['GPLMUX51'] = 1
|
|
p['GPLMUX52'] = 1
|
|
p['GPLMUX53'] = 1
|
|
p['GPLMUX54'] = 1
|
|
p['GPLMUX55'] = 1
|
|
p['GPLMUX56'] = 1
|
|
p['GPLMUX57'] = 1
|
|
p['GPLMUX58'] = 1
|
|
p['GPLMUX59'] = 1
|
|
p['GPLMUX60'] = 1
|
|
p['GPLMUX61'] = 1
|
|
p['GPLMUX62'] = 1
|
|
p['GPLMUX63'] = 1
|
|
p['GPLMUX64'] = 1
|
|
p['GPLMUX65'] = 1
|
|
p['GPLMUX66'] = 1
|
|
p['GPLMUX67'] = 1
|
|
p['GPLMUX68'] = 1
|
|
p['GPLMUX69'] = 1
|
|
p['GPLMUX70'] = 1
|
|
p['NANDUSEFPGA'] = 0
|
|
p['UART0USEFPGA'] = 0
|
|
p['RGMII1USEFPGA'] = 0
|
|
p['SPIS0USEFPGA'] = 0
|
|
p['CAN0USEFPGA'] = 0
|
|
p['I2C0USEFPGA'] = 0
|
|
p['SDMMCUSEFPGA'] = 0
|
|
p['QSPIUSEFPGA'] = 0
|
|
p['SPIS1USEFPGA'] = 0
|
|
p['RGMII0USEFPGA'] = 0
|
|
p['UART1USEFPGA'] = 0
|
|
p['CAN1USEFPGA'] = 0
|
|
p['USB1USEFPGA'] = 0
|
|
p['I2C3USEFPGA'] = 0
|
|
p['I2C2USEFPGA'] = 0
|
|
p['I2C1USEFPGA'] = 0
|
|
p['SPIM1USEFPGA'] = 0
|
|
p['USB0USEFPGA'] = 0
|
|
p['SPIM0USEFPGA'] = 0
|
|
|
|
return p
|
|
|
|
|
|
def get_default_pinmux_configs(self):
|
|
""" Get default pinmux values """
|
|
p = collections.OrderedDict()
|
|
|
|
p['rgmii0'] = { 'name': 'CFG_HPS_EMAC0', 'used': 0 }
|
|
p['rgmii1'] = { 'name': 'CFG_HPS_EMAC1', 'used': 0 }
|
|
p['usb0'] = { 'name': 'CFG_HPS_USB0', 'used': 0 }
|
|
p['usb1'] = { 'name': 'CFG_HPS_USB1', 'used': 0 }
|
|
p['nand'] = { 'name': 'CFG_HPS_NAND', 'used': 0 }
|
|
p['sdmmc'] = { 'name': 'CFG_HPS_SDMMC', 'used': 0 }
|
|
p['CFG_HPS_SDMMC_BUSWIDTH'] = { 'name': 'CFG_HPS_SDMMC_BUSWIDTH', 'used': 0 }
|
|
p['qspi'] = { 'name': 'CFG_HPS_QSPI', 'used': 0 }
|
|
p['CFG_HPS_QSPI_CS3'] = { 'name': 'CFG_HPS_QSPI_CS3', 'used': 0 }
|
|
p['CFG_HPS_QSPI_CS2'] = { 'name': 'CFG_HPS_QSPI_CS2', 'used': 0 }
|
|
p['CFG_HPS_QSPI_CS1'] = { 'name': 'CFG_HPS_QSPI_CS1', 'used': 0 }
|
|
p['CFG_HPS_QSPI_CS0'] = { 'name': 'CFG_HPS_QSPI_CS0', 'used': 0 }
|
|
p['uart0'] = { 'name': 'CFG_HPS_UART0', 'used': 0 }
|
|
p['CFG_HPS_UART0_TX'] = { 'name': 'CFG_HPS_UART0_TX', 'used': 0 }
|
|
p['CFG_HPS_UART0_CTS'] = { 'name': 'CFG_HPS_UART0_CTS', 'used': 0 }
|
|
p['CFG_HPS_UART0_RTS'] = { 'name': 'CFG_HPS_UART0_RTS', 'used': 0 }
|
|
p['CFG_HPS_UART0_RX'] = { 'name': 'CFG_HPS_UART0_RX', 'used': 0 }
|
|
p['uart1'] = { 'name': 'CFG_HPS_UART1', 'used': 0 }
|
|
p['CFG_HPS_UART1_TX'] = { 'name': 'CFG_HPS_UART1_TX', 'used': 0 }
|
|
p['CFG_HPS_UART1_CTS'] = { 'name': 'CFG_HPS_UART1_CTS', 'used': 0 }
|
|
p['CFG_HPS_UART1_RTS'] = { 'name': 'CFG_HPS_UART1_RTS', 'used': 0 }
|
|
p['CFG_HPS_UART1_RX'] = { 'name': 'CFG_HPS_UART1_RX', 'used': 0 }
|
|
p['trace'] = { 'name': 'CFG_HPS_TRACE', 'used': 0 }
|
|
p['i2c0'] = { 'name': 'CFG_HPS_I2C0', 'used': 0 }
|
|
p['i2c1'] = { 'name': 'CFG_HPS_I2C1', 'used': 0 }
|
|
p['i2c2'] = { 'name': 'CFG_HPS_I2C2', 'used': 0 }
|
|
p['i2c3'] = { 'name': 'CFG_HPS_I2C3', 'used': 0 }
|
|
p['spim0'] = { 'name': 'CFG_HPS_SPIM0', 'used': 0 }
|
|
p['spim1'] = { 'name': 'CFG_HPS_SPIM1', 'used': 0 }
|
|
p['spis0'] = { 'name': 'CFG_HPS_SPIS0', 'used': 0 }
|
|
p['spis1'] = { 'name': 'CFG_HPS_SPIS1', 'used': 0 }
|
|
p['can0'] = { 'name': 'CFG_HPS_CAN0', 'used': 0 }
|
|
p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
|
|
|
|
p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
|
|
p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
|
|
p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
|
|
p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
|
|
|
|
return p
|
|
|
|
def updateTemplate(self, name, value):
|
|
""" Update Makefile & reset_config.h """
|
|
pattern = "${" + name + "}"
|
|
self.makefileTemplate = self.makefileTemplate.replace(pattern, value)
|
|
self.resetConfigHTemplate = self.resetConfigHTemplate.replace(pattern, value)
|
|
|
|
def romanToInteger(self, roman):
|
|
"""
|
|
Convert roman numerals to integer
|
|
Since we only support I,V,X, the
|
|
supported range is 1-39
|
|
"""
|
|
table = { 'I':1 , 'V':5, 'X':10 }
|
|
|
|
literals = list(roman)
|
|
|
|
value = 0
|
|
i = 0
|
|
|
|
while(i < (len(literals) - 1)):
|
|
current = table[literals[i]]
|
|
next = table[literals[i + 1]]
|
|
if (current < next):
|
|
value += (next - current)
|
|
i += 2
|
|
else:
|
|
value += current
|
|
i += 1
|
|
|
|
if (i < (len(literals))):
|
|
value += table[literals[i]]
|
|
|
|
return value
|
|
|
|
def getDeviceFamily(self):
|
|
""" Get device family """
|
|
return self.derivedDeviceFamily
|
|
|
|
def getDeviceFamilyName(self, deviceFamily):
|
|
""" Get device family name """
|
|
p = re.compile('^(\w+)\s+(\w+)$')
|
|
m = p.match(deviceFamily)
|
|
return m.group(1).lower() + str(self.romanToInteger(m.group(2)))
|
|
|
|
def handleHPSSystemNode(self, systemNode):
|
|
""" handleHPSPeripheralsNode(peripheralsNode)
|
|
peripheralsNode is a peripherals element node in hps.xml
|
|
peripheralsNode is a list of peripheralNodes
|
|
"""
|
|
configNode = xmlgrok.firstElementChild(systemNode)
|
|
while configNode != None:
|
|
|
|
name = configNode.getAttribute('name')
|
|
value = configNode.getAttribute('value')
|
|
|
|
self.updateTemplate(name, value)
|
|
|
|
if name == "DEVICE_FAMILY":
|
|
self.derivedDeviceFamily = self.getDeviceFamilyName(value)
|
|
|
|
if name == "DMA_Enable":
|
|
self.dmaEnable = value
|
|
|
|
configNode = xmlgrok.nextElementSibling(configNode)
|
|
|
|
def handleHPSPeripheralNode(self, peripheralNode):
|
|
""" This node of the hps.xml may contain a name, value pair
|
|
We need to:
|
|
emit a #define for the peripheral for is 'used' state
|
|
emit a #define for that pair, if it is marked 'used'
|
|
"""
|
|
peripheralNode = xmlgrok.firstElementChild(peripheralNode)
|
|
|
|
while peripheralNode != None:
|
|
if peripheralNode.hasAttribute('name') and peripheralNode.hasAttribute('used'):
|
|
newLine = "\n"
|
|
name = peripheralNode.getAttribute('name')
|
|
used = peripheralNode.getAttribute('used')
|
|
|
|
if used == 'true' or used == True:
|
|
used = 1
|
|
elif used == 'false' or used == False:
|
|
used = 0
|
|
|
|
configs = collections.OrderedDict()
|
|
|
|
configNode = xmlgrok.firstElementChild(peripheralNode)
|
|
while configNode != None:
|
|
config_define_name = configNode.getAttribute('name')
|
|
config_define_value = configNode.getAttribute('value')
|
|
configs[config_define_name] = config_define_value
|
|
configNode = xmlgrok.nextElementSibling(configNode)
|
|
if configNode == None:
|
|
newLine += newLine
|
|
self.pinmuxConfigBuffer.write("#define " + str(config_define_name) + ' ' + '(' + str(config_define_value) + ')' + newLine)
|
|
|
|
entry = self.pinmux_configs[name]
|
|
define_name = entry['name']
|
|
|
|
if (len(configs) > 0):
|
|
self.pinmux_configs[name] = { 'name': define_name, 'used': used, 'configs': configs }
|
|
else:
|
|
self.pinmux_configs[name] = { 'name': define_name, 'used': used }
|
|
|
|
# skip the parent peripheral node
|
|
# since only need to define child config node(s)
|
|
peripheralNode = xmlgrok.nextElementSibling(peripheralNode)
|
|
|
|
def handleHPSPinmuxNode(self, pinmuxNode):
|
|
""" For a pinmuxNode, we may emit a #define for the name, value pair
|
|
"""
|
|
if pinmuxNode.hasAttribute('name') and pinmuxNode.hasAttribute('value'):
|
|
self.pinmuxArraySize += 1
|
|
name = pinmuxNode.getAttribute('name')
|
|
value = pinmuxNode.getAttribute('value')
|
|
|
|
def handleHPSPinmuxesNode(self, pinmuxesNode):
|
|
""" PinmuxesNode is a list of pinmuxNodes
|
|
"""
|
|
self.pinmuxHeaderBuffer.write(str("const u8 sys_mgr_init_table[] = {\n"))
|
|
|
|
pinmuxNode = xmlgrok.firstElementChild(pinmuxesNode)
|
|
while pinmuxNode != None:
|
|
if pinmuxNode.hasAttribute('name') and pinmuxNode.hasAttribute('value'):
|
|
self.pinmuxArraySize += 1
|
|
name = pinmuxNode.getAttribute('name')
|
|
value = pinmuxNode.getAttribute('value')
|
|
self.pinmux_regs[name] = value
|
|
pinmuxNode = xmlgrok.nextElementSibling(pinmuxNode)
|
|
|
|
reg_count = 0
|
|
pinmux_regs_count = len(self.pinmux_regs)
|
|
for reg, value in self.pinmux_regs.items():
|
|
reg_count += 1
|
|
if reg_count < pinmux_regs_count:
|
|
self.pinmuxHeaderBuffer.write(str("\t" + str(value) + ', /* ' + reg + ' */\n' ))
|
|
else:
|
|
self.pinmuxHeaderBuffer.write(str("\t" + str(value) + ' /* ' + reg + ' */\n' ))
|
|
|
|
# Write the close of the pin MUX array in the header
|
|
self.pinmuxHeaderBuffer.write(str("};" ))
|
|
|
|
def handleHPSClockNode(self, clockNode):
|
|
""" A clockNode may emit a #define for the name, frequency pair
|
|
"""
|
|
if clockNode.hasAttribute('name') and clockNode.hasAttribute('frequency'):
|
|
name = clockNode.getAttribute('name')
|
|
frequency = clockNode.getAttribute('frequency')
|
|
self.clockStream.write("#define " + name + ' ' + '(' + frequency + ')' + '\n')
|
|
|
|
def handleHPSClocksNode(self, clocksNode):
|
|
""" A list of clockNodes is call clocksNode
|
|
"""
|
|
self.clockStream = streamer.Streamer(self.outputDir + os.sep + clocksNode.nodeName + '.h', 'w')
|
|
self.clockStream.open()
|
|
clockNode = xmlgrok.firstElementChild(clocksNode)
|
|
while clockNode != None:
|
|
self.handleHPSClockNode(clockNode)
|
|
clockNode = xmlgrok.nextElementSibling(clockNode)
|
|
|
|
self.clockStream.close()
|
|
|
|
def handleHpsFpgaInterfaces(self, node):
|
|
""" Update FPGA Interface registers """
|
|
node = xmlgrok.firstElementChild(node)
|
|
|
|
while node != None:
|
|
name = node.getAttribute('name')
|
|
used = node.getAttribute('used')
|
|
|
|
if used == 'true':
|
|
reset = 0
|
|
else:
|
|
reset = 1
|
|
|
|
if name == 'F2H_AXI_SLAVE':
|
|
self.updateTemplate("DERIVED_RESET_ASSERT_FPGA2HPS", str(reset))
|
|
elif name == 'H2F_AXI_MASTER':
|
|
self.updateTemplate("DERIVED_RESET_ASSERT_HPS2FPGA", str(reset))
|
|
elif name == 'LWH2F_AXI_MASTER':
|
|
self.updateTemplate("DERIVED_RESET_ASSERT_LWHPS2FPGA", str(reset))
|
|
|
|
node = xmlgrok.nextElementSibling(node)
|
|
|
|
def createFilesFromHPS(self):
|
|
""" Parse xml and create pinmux_config.h """
|
|
# Unfortunately we can't determine the file name before
|
|
# parsing the XML, so let's build up the source file
|
|
# content in string buffer
|
|
self.pinmuxHeaderBuffer = CompatStringIO()
|
|
self.pinmuxConfigBuffer = CompatStringIO()
|
|
|
|
# Get a list of all nodes with the hps element name
|
|
hpsNodeList = self.dom.getElementsByTagName('hps')
|
|
if len(hpsNodeList) > 1:
|
|
print ("*** WARNING:" + "Multiple hps Elements found in %s!" % self.hpsInFileName)
|
|
# For each of the hps element nodes, go through the child list
|
|
# Note that currently there is only one hps Element
|
|
# but this code will handle more than one hps node
|
|
# In the future, multiple hps nodes may need additional code
|
|
# to combine settings from the multiple hps Elements
|
|
for hpsNode in hpsNodeList:
|
|
# Currently, there are only 3 children of the hps Element:
|
|
# peripherals, pin_muxes, and clocks
|
|
# but this is left open-ended for future additions to the
|
|
# specification for the hps.xml
|
|
childNode = xmlgrok.firstElementChild(hpsNode)
|
|
while childNode != None:
|
|
if childNode.nodeName == 'pin_muxes':
|
|
self.handleHPSPinmuxesNode(childNode)
|
|
elif childNode.nodeName == 'system':
|
|
self.handleHPSSystemNode(childNode)
|
|
elif childNode.nodeName == 'fpga_interfaces':
|
|
self.handleHpsFpgaInterfaces(childNode)
|
|
elif childNode.nodeName == 'peripherals':
|
|
self.handleHPSPeripheralNode(childNode)
|
|
else:
|
|
print ("***Error:Found unexpected HPS child node:%s" % childNode.nodeName)
|
|
childNode = xmlgrok.nextElementSibling(childNode)
|
|
|
|
self.updateTemplate("DERIVED_DEVICE_FAMILY", self.derivedDeviceFamily)
|
|
|
|
# Now we write string buffers into files once we know the device family
|
|
self.pinmux_config_h = 'pinmux_config.h'
|
|
self.pinmux_config_src = 'pinmux_config_' + self.derivedDeviceFamily + '.c'
|
|
|
|
# Create pinmux_config .h
|
|
headerDefine = "__SOCFPGA_PINMUX_CONFIG_H__"
|
|
self.pinmuxHeaderFile = streamer.Streamer(self.outputDir + os.sep + self.pinmux_config_h, 'w')
|
|
self.pinmuxHeaderFile.open()
|
|
self.pinmuxHeaderFile.writeLicenseHeader()
|
|
self.pinmuxHeaderFile.write('/*\n * Altera SoCFPGA PinMux configuration\n */\n\n')
|
|
|
|
self.pinmuxHeaderFile.write("#ifndef " + headerDefine + "\n")
|
|
self.pinmuxHeaderFile.write("#define " + headerDefine + "\n\n")
|
|
self.pinmuxHeaderFile.write(self.pinmuxHeaderBuffer.getvalue())
|
|
self.pinmuxHeaderFile.write("\n#endif /* " + headerDefine + " */\n")
|
|
self.pinmuxHeaderFile.close()
|
|
|
|
# Free up string buffers
|
|
self.pinmuxHeaderBuffer.close()
|
|
self.pinmuxConfigBuffer.close()
|