Commit 496a0d6f authored by Eyesisbox Elphel's avatar Eyesisbox Elphel
Browse files

Working on DDR configuration

parent 5b2e54e8
Loading
Loading
Loading
Loading

ddrcfg_defs.py

0 → 100644
+112 −0
Original line number Original line Diff line number Diff line
#!/usr/bin/env python
# Copyright (C) 2013, Elphel.inc.
# Definitions of configuration parameters for DDR memory 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2013, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
DDR_CFG_DEFS={
    'TARGET_FREQ_MHZ': {'CONF_NAME':'CONFIG_EZYNQ_DDR_TARGET_FREQ_MHZ','TYPE':'F','MANDATORY':True,'DERIVED':True,'DEFAULT':533.333333,
                'DESCRIPTION':'Target DDR clock frequency in MHz (actual frequency will depend on the clock/clock muxes)'},              
    'FREQ_MHZ':        {'CONF_NAME':'CONFIG_EZYNQ_DDR_FREQ_MHZ','TYPE':'F','MANDATORY':True,'DERIVED':True,'DEFAULT':533.333333,
                'DESCRIPTION':'Actual DDR clock frequency in MHz, may be derived form CONFIG_EZYNQ_DDR_TARGET_FREQ_MHZ and clock multiplexer settings'},              
    'CL':              {'CONF_NAME':'CONFIG_EZYNQ_DDR_CL','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':7,
                'DESCRIPTION':'CAS read latency (in tCK)'},              
    'AL':              {'CONF_NAME':'CONFIG_EZYNQ_DDR_CL','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':0,
                'DESCRIPTION':'Posted CAS additive latency (in tCK)'},              
    'CWL':             {'CONF_NAME':'CONFIG_EZYNQ_DDR_CWL','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':6,
                'DESCRIPTION':'CAS write latency (in tCK)'},              
    'RCD':             {'CONF_NAME':'CONFIG_EZYNQ_DDR_RCD','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':7,
                'DESCRIPTION':'RAS to CAS delay (in tCK)'},              
    'RP':              {'CONF_NAME':'CONFIG_EZYNQ_DDR_RP','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':7,
                'DESCRIPTION':'Row Precharge time (in tCK)'},              
    'T_RC':            {'CONF_NAME':'CONFIG_EZYNQ_DDR_T_RC','TYPE':'F','MANDATORY':True,'DERIVED':False,'DEFAULT':48.75,
                'DESCRIPTION':'Activate to Activate or Refresh command period (ns)'},              
    'T_RAS_MIN':       {'CONF_NAME':'CONFIG_EZYNQ_DDR_T_RAS_MIN','TYPE':'F','MANDATORY':True,'DERIVED':False,'DEFAULT':35.0,
                'DESCRIPTION':'Minimal Row Active time (ns)'},              
    'T_FAW':           {'CONF_NAME':'CONFIG_EZYNQ_DDR_T_FAW','TYPE':'F','MANDATORY':True,'DERIVED':False,'DEFAULT':40.0,
                'DESCRIPTION':'Minimal running window for 4 page activates (ns)'},              
    'BANK_ADDR_COUNT': {'CONF_NAME':'CONFIG_EZYNQ_DDR_BANK_ADDR_COUNT','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':3,
                'Number of DDR banks'},              
    'ROW_ADDR_COUNT':  {'CONF_NAME':'CONFIG_EZYNQ_DDR_ROW_ADDR_COUNT','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':15,
                'Number of DDR banks'},              
    'COL_ADDR_COUNT':  {'CONF_NAME':'CONFIG_EZYNQ_DDR_COL_ADDR_COUNT','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':10,
                'Number of DDR banks'},              
    'ENABLE':          {'CONF_NAME':'CONFIG_EZYNQ_DDR_ENABLE','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':True,
                'Enable DDR memory'},              
    'MEMORY_TYPE':     {'CONF_NAME':'CONFIG_EZYNQ_DDR_MEMORY_TYPE','TYPE':('DDR3','DDR2','LPDDR2'),'MANDATORY':True,'DERIVED':False,'DEFAULT':'DDR3',
                'DDR memory type'},              
    'ECC':             {'CONF_NAME':'CONFIG_EZYNQ_DDR_ECC','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':False,
                'Enable ECC for the DDR memory'},
    'BUS_WIDTH':       {'CONF_NAME':'CONFIG_EZYNQ_DDR_BUS_WIDTH','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':32,
                'SoC DDR bus width'},
    'BL':              {'CONF_NAME':'CONFIG_EZYNQ_DDR_BL','TYPE':(4,8),'MANDATORY':True,'DERIVED':False,'DEFAULT':8, # DDR2 may have different lengths?
                'Burst length'},
    'HIGH_TEMP':       {'CONF_NAME':'CONFIG_EZYNQ_DDR_HIGH_TEMP','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
                'High temperature (influences refresh)'},
    'PARTNO':          {'CONF_NAME':'CONFIG_EZYNQ_DDR_PARTNO','TYPE':'T','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
                'Memory part number  (currently not used - derive some parameters late)'},
    'DRAM_WIDTH':      {'CONF_NAME':'CONFIG_EZYNQ_DDR_DRAM_WIDTH','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':16,
                'Memory chip bus width'},
    'SPEED_BIN':       {'CONF_NAME':'CONFIG_EZYNQ_DDR_SPEED_BIN','TYPE':'T','MANDATORY':True,'DERIVED':False,'DEFAULT':16,
                'Memory speed bin (currently not used - derive timing later)'},
    'TRAIN_WRITE_LEVEL':{'CONF_NAME':'CONFIG_EZYNQ_DDR_TRAIN_WRITE_LEVEL','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
                'Automatically train write leveling during initialization'},
    'TRAIN_READ_GATE': {'CONF_NAME':'CONFIG_EZYNQ_DDR_TRAIN_READ_GATE','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
                'Automatically train read gate timing during initialization'},
    'TRAIN_DATA_EYE':  {'CONF_NAME':'CONFIG_EZYNQ_DDR_TRAIN_DATA_EYE','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
                'Automatically train data eye during initialization'},
    'CLOCK_STOP_EN':   {'CONF_NAME':'CONFIG_EZYNQ_DDR_CLOCK_STOP_EN','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
                'Enable clock stop'},
    'INTERNAL_VREF':   {'CONF_NAME':'CONFIG_EZYNQ_DDR_USE_INTERNAL_VREF','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
                'Use internal Vref'},
                            
                            
}
#TODO make some of (possibly) derived, leave '_T_' for ns only!
# CONFIG_EZYNQ_DDR_FREQ_MHZ = 533.333333 *
# CONFIG_EZYNQ_DDR_CL = 7  *
# CONFIG_EZYNQ_DDR_CWL = 6  *
# CONFIG_EZYNQ_DDR_RCD = 7 (was CONFIG_EZYNQ_DDR_T_RCD = 7) *
# CONFIG_EZYNQ_DDR_RP = 7 (was CONFIG_EZYNQ_DDR_T_RP = 7) *
# CONFIG_EZYNQ_DDR_T_RC = 48.75 *
# CONFIG_EZYNQ_DDR_T_RAS_MIN = 35.0 *
# CONFIG_EZYNQ_DDR_T_FAW = 40.0 *
# CONFIG_EZYNQ_DDR_AL = 0 *
# CONFIG_EZYNQ_DDR_BANK_ADDR_COUNT = 3 *
# CONFIG_EZYNQ_DDR_ROW_ADDR_COUNT = 15 *
# CONFIG_EZYNQ_DDR_COL_ADDR_COUNT = 10 *

# CONFIG_EZYNQ_DDR_ENABLE = 1          *
# CONFIG_EZYNQ_DDR_MEMORY_TYPE = DDR3  *
# CONFIG_EZYNQ_DDR_ECC = Disabled      *
# CONFIG_EZYNQ_DDR_BUS_WIDTH = 32      *
# CONFIG_EZYNQ_DDR_BL = 8              *   
# CONFIG_EZYNQ_DDR_HIGH_TEMP = Normal  *
# CONFIG_EZYNQ_DDR_PARTNO = MT41K256M16RE-125 *
# CONFIG_EZYNQ_DDR_DRAM_WIDTH = 16     *
# CONFIG_EZYNQ_DDR_SPEED_BIN = DDR3_1066F *
# CONFIG_EZYNQ_DDR_TRAIN_WRITE_LEVEL = 0
# CONFIG_EZYNQ_DDR_TRAIN_READ_GATE = 0
# CONFIG_EZYNQ_DDR_TRAIN_DATA_EYE = 0
# CONFIG_EZYNQ_DDR_CLOCK_STOP_EN = 0
# CONFIG_EZYNQ_DDR_USE_INTERNAL_VREF = 0

#CONFIG_EZYNQ_DDR_DEVICE_CAPACITY_MBITS = 4096 - can be calculated

ezynq_ddr.py

0 → 100755
+59 −0
Original line number Original line Diff line number Diff line
#!/usr/bin/env python
# Copyright (C) 2013, Elphel.inc.
# configuration of the DDR-related registers
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2013, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
import ezynq_ddrc_defs
import ezynq_registers
class EzynqDDR:
    def __init__(self,permit_undefined_bits=False,force=False,warn=False):
        self.DDRC_DEFS=ezynq_ddrc_defs.DDRC_DEFS
        self.register_sets= {'PRE':ezynq_registers.EzynqRegisters(self.DDRC_DEFS,0,permit_undefined_bits),
                            'MAIN':ezynq_registers.EzynqRegisters(self.DDRC_DEFS,0,permit_undefined_bits),
                            'POST':ezynq_registers.EzynqRegisters(self.DDRC_DEFS,0,permit_undefined_bits)}
#        self.set_names=('PRE','MAIN','POST')
        self.set_attribs=(
                          {'NAME':'PRE','POSTFIX':'_PRE','PREFIX':'CONFIG_EZYNQ_DDR_SETREG_','TITLE':"DDR Controller Register Pre-Set"},
                          {'NAME':'MAIN','POSTFIX':'','PREFIX':'CONFIG_EZYNQ_DDR_SETREG_','TITLE':"DDR Controller Register Set"},
                          {'NAME':'POST','POSTFIX':'_POST','PREFIX':'CONFIG_EZYNQ_DDR_SETREG_','TITLE':"DDR Controller Register Post-Set"})
        self.postfixes=[attrib['POSTFIX'] for attrib in self.set_attribs]
    def parse_raw_register_set(self,raw_configs,qualifier_char,force=True,warn=True):
#        for i,attribs in enumerate(self.set_attribs):
        for attribs in self.set_attribs:
            reg_set_name=attribs['NAME']
            reg_set= self.register_sets[reg_set_name]
            prefix= attribs['PREFIX']
            postfix= attribs['POSTFIX']
            reg_set.parse_options_set(raw_configs,prefix,postfix,self.postfixes,qualifier_char,force,warn) #force - readonly/undefined fields, warn: data does not fit in the bit field
    def print_html_registers(self, html_file, show_bit_fields=True, show_comments=True):
        for attribs in self.set_attribs:
            reg_set_name=attribs['NAME']
            reg_set= self.register_sets[reg_set_name]
            if len(reg_set.get_reg_names())>0:
                html_file.write('<h2>'+attribs['TITLE']+'</h2>\n')
                reg_set.print_html_registers(html_file, show_bit_fields, show_comments)
                html_file.write('<br/>\n')
               
#ddr=Ezynq_DDR()
#print ddr.DDRC_DEFS
#    def __init__(self,defines,channel=0,permit_undefined_bits=False):
#    def parse_options_set(self,raw_configs,prefix,postfix,qualifier_char,force=True,warn=True): #force - readonly/undefined fields, warn: data does not fit in the bit field
   
 No newline at end of file

ezynq_ddrc_defs.py

0 → 100755
+653 −0

File added.

Preview size limit exceeded, changes collapsed.

ezynq_registers.py

0 → 100644
+347 −0

File added.

Preview size limit exceeded, changes collapsed.

+102 −71
Original line number Original line Diff line number Diff line
@@ -22,6 +22,8 @@ __maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__email__ = "andrey@elphel.com"
__status__ = "Development"
__status__ = "Development"
import struct
import struct
import ezynq_ddr

# http://docs.python.org/2/howto/argparse.html
# http://docs.python.org/2/howto/argparse.html
import argparse
import argparse
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser()
@@ -36,33 +38,33 @@ args = parser.parse_args()
#print args
#print args
#print args.configs
#print args.configs



ERROR_DEFS={
ERR_WRONG_USAGE=1    
    'WRONG_USAGE':1,    
ERR_MISSING_CONFIG = 2    
    'MISSING_CONFIG': 2,    
ERR_INVALID = 3
    'INVALID': 3,
ERR_NOSUCHPIN = 4
    'NOSUCHPIN': 4,
ERR_NOSUCHSIGNAL = 5
    'NOSUCHSIGNAL': 5,
ERR_MIOCONFLICT = 6
    'MIOCONFLICT':6,
ERR_INOUT = 7
    'INOUT': 7,
ERR_HEAD = 8
    'HEAD': 8,
ERR_NONACCESSIBLE_REHGISTER = 9
    'NONACCESSIBLE_REGISTER': 9,
ERR_NOT_IMPLEMENTED=10
    'NOT_IMPLEMENTED':10}
                                                   


COMMENT_CHAR = '#'
COMMENT_CHAR = '#'
OPTION_CHAR = '='
OPTION_CHAR = '='
QULAIFIER_CHAR = '__'
QUALIFIER_CHAR = '__'


if not args.configs:
if not args.configs:
    parser.print_help()
    parser.print_help()
    exit (ERR_WRONG_USAGE)
    exit (ERROR_DEFS['WRONG_USAGE'])
WARN=args.warn
WARN=args.warn
MIO_HTML=args.html
MIO_HTML=args.html
try:
try:
    MIO_HTML_MASK=int(args.html_mask)
    MIO_HTML_MASK=int(args.html_mask,0)
except:
except:
    MIO_HTML_MASK=0
    MIO_HTML_MASK=0


    
MIO_TEMPLATES = {
MIO_TEMPLATES = {
  'QUADSPI':(
  'QUADSPI':(
     {'NAME':'CS0',  'TRISTATE':False, 'FAST':True, 'PULLUP':True,  'L0':1, 'L1':0, 'L2':0, 'L3':0, 'PINS':((1,), (0,))},
     {'NAME':'CS0',  'TRISTATE':False, 'FAST':True, 'PULLUP':True,  'L0':1, 'L1':0, 'L2':0, 'L3':0, 'PINS':((1,), (0,))},
@@ -296,6 +298,8 @@ MIO_ATTR=[
    {'PREFIX':'CONFIG_EZYNQ_MIO_INOUT_',    'SPECIAL':'DIR'},
    {'PREFIX':'CONFIG_EZYNQ_MIO_INOUT_',    'SPECIAL':'DIR'},
    {'PREFIX':'CONFIG_EZYNQ_MIO_GPIO_OUT_', 'SPECIAL':'GPIO_OUT'}]
    {'PREFIX':'CONFIG_EZYNQ_MIO_GPIO_OUT_', 'SPECIAL':'GPIO_OUT'}]




GPIO_MASKDATA=[
GPIO_MASKDATA=[
               {'NAME':'MASK_DATA_0_LSW','ADDRESS':0xE000A000,'DATA':0},
               {'NAME':'MASK_DATA_0_LSW','ADDRESS':0xE000A000,'DATA':0},
               {'NAME':'MASK_DATA_0_MSW','ADDRESS':0xE000A004,'DATA':0},
               {'NAME':'MASK_DATA_0_MSW','ADDRESS':0xE000A004,'DATA':0},
@@ -326,16 +330,13 @@ ACCESSIBLE_REGISTERS=((0xe0001000,0xe0001fff), # UART1 controller registers
                      (0xf8000a00,0xf8000a8c), # SLCR registers All shown "reserved" ???
                      (0xf8000a00,0xf8000a8c), # SLCR registers All shown "reserved" ???
                      (0xf8000ab0,0xf8000b74)) # SLCR registers iostd, voltages,  - more DDR stuff
                      (0xf8000ab0,0xf8000b74)) # SLCR registers iostd, voltages,  - more DDR stuff
           
           
#TODO: list configurable interfaces (ordered list) and process it in the defined order
#Each interface may have channel and always has name (as in MIO_TEMPLATES)




  
  
if args.verbosity >= 2:
if args.verbosity >= 2:
    print MIO_TEMPLATES
    print MIO_TEMPLATES
def parse_config(filename):
def read_config(filename):
    attrib_suffix='ATTRIB'
    raw_configs = []
    options = {}
    f = open(filename)
    f = open(filename)
    for line in f:
    for line in f:
        # First, remove comments:
        # First, remove comments:
@@ -349,9 +350,19 @@ def parse_config(filename):
            # strip spaces:
            # strip spaces:
            option = option.strip()
            option = option.strip()
            value = value.strip().upper()
            value = value.strip().upper()
            # strip quotes:
            value = value.strip('"')
            value = value.strip('"')
            if QULAIFIER_CHAR in option:
            raw_configs.append({'KEY':option,'VALUE':value})
                option,qualifier=option.split(QULAIFIER_CHAR,1)
    f.close()
    return raw_configs
def parse_config_mio(raw_configs):
    attrib_suffix='ATTRIB'
    options = {}
    for line in raw_configs:
        option = line['KEY']
        value = line['VALUE']
        if QUALIFIER_CHAR in option:
            option,qualifier=option.split(QUALIFIER_CHAR,1)
            if not option in options:
            if not option in options:
                options[option]={}
                options[option]={}
            if not isinstance(options[option],dict): # make a former value a value in a dictionary
            if not isinstance(options[option],dict): # make a former value a value in a dictionary
@@ -367,7 +378,7 @@ def parse_config(filename):
            else:        
            else:        
                options[option][qualifier]=value    
                options[option][qualifier]=value    
        else: 
        else: 
            # store in dictionary:
        # store in the dictionary:
            if option in options:
            if option in options:
                try:
                try:
                    options[option]['INTERFACE_GROUP'] = value #qualified pins already defined
                    options[option]['INTERFACE_GROUP'] = value #qualified pins already defined
@@ -375,7 +386,6 @@ def parse_config(filename):
                    options[option] = value # not a dictionary - just overwrite 
                    options[option] = value # not a dictionary - just overwrite 
            else:
            else:
                options[option] = value
                options[option] = value
    f.close()
    return options
    return options


def mio_set_defaults(mio_dflts, mio, options):
def mio_set_defaults(mio_dflts, mio, options):
@@ -385,20 +395,20 @@ def mio_set_defaults(mio_dflts, mio, options):
        mio_dflts['MIO_0_VOLT'] = float(options['CONFIG_EZYNQ_MIO_0_VOLT'])
        mio_dflts['MIO_0_VOLT'] = float(options['CONFIG_EZYNQ_MIO_0_VOLT'])
    except (KeyError):
    except (KeyError):
        print "required CONFIG_EZYNQ_MIO_0_VOLT is not defined. It should be 1.8, 2.5 or 3.3"
        print "required CONFIG_EZYNQ_MIO_0_VOLT is not defined. It should be 1.8, 2.5 or 3.3"
        exit (ERR_MISSING_CONFIG)
        exit (ERROR_DEFS['MISSING_CONFIG'])
    if not mio_dflts['MIO_0_VOLT'] in VALID_VOLTAGES:
    if not mio_dflts['MIO_0_VOLT'] in VALID_VOLTAGES:
        print 'Invalid voltage specified for MIO bank 0: CONFIG_EZYNQ_MIO_0_VOLT = ' + options['CONFIG_EZYNQ_MIO_0_VOLT']
        print 'Invalid voltage specified for MIO bank 0: CONFIG_EZYNQ_MIO_0_VOLT = ' + options['CONFIG_EZYNQ_MIO_0_VOLT']
        print 'Valid values are : ' + str(VALID_VOLTAGES)
        print 'Valid values are : ' + str(VALID_VOLTAGES)
        exit (ERR_INVALID)
        exit (ERROR_DEFS['INVALID'])
    try:
    try:
        mio_dflts['MIO_1_VOLT'] = float(options['CONFIG_EZYNQ_MIO_1_VOLT'])
        mio_dflts['MIO_1_VOLT'] = float(options['CONFIG_EZYNQ_MIO_1_VOLT'])
    except (KeyError):
    except (KeyError):
        print "required CONFIG_EZYNQ_MIO_1_VOLT is not defined. It should be 1.8, 2.5 or 3.3"
        print "required CONFIG_EZYNQ_MIO_1_VOLT is not defined. It should be 1.8, 2.5 or 3.3"
        exit (ERR_MISSING_CONFIG)
        exit (ERROR_DEFS['MISSING_CONFIG'])
    if not mio_dflts['MIO_1_VOLT'] in VALID_VOLTAGES:
    if not mio_dflts['MIO_1_VOLT'] in VALID_VOLTAGES:
        print 'Invalid voltage specified for MIO bank 1: CONFIG_EZYNQ_MIO_1_VOLT = ' + options['CONFIG_EZYNQ_MIO_1_VOLT']
        print 'Invalid voltage specified for MIO bank 1: CONFIG_EZYNQ_MIO_1_VOLT = ' + options['CONFIG_EZYNQ_MIO_1_VOLT']
        print 'Valid values are : ' + str(VALID_VOLTAGES)
        print 'Valid values are : ' + str(VALID_VOLTAGES)
        exit (ERR_INVALID)
        exit (ERROR_DEFS['INVALID'])
    iostd0 = IOSTD[VALID_VOLTAGES.index(mio_dflts['MIO_0_VOLT'])]
    iostd0 = IOSTD[VALID_VOLTAGES.index(mio_dflts['MIO_0_VOLT'])]
    pullup0 = False
    pullup0 = False
    if 'CONFIG_EZYNQ_MIO_0_PULLUP' in options:
    if 'CONFIG_EZYNQ_MIO_0_PULLUP' in options:
@@ -452,7 +462,7 @@ def set_mio_interfaces(mio_interfaces, options):
                        for pin in func_pin['PINS'][channel]:
                        for pin in func_pin['PINS'][channel]:
                            allowed_pins.append(pin)
                            allowed_pins.append(pin)
                    print 'Allowed MIO pins are:',allowed_pins
                    print 'Allowed MIO pins are:',allowed_pins
                    exit (ERR_NOSUCHPIN)
                    exit (ERROR_DEFS['NOSUCHPIN'])
                for tmpl_pin in iface_template:
                for tmpl_pin in iface_template:
                    iface_pin={}
                    iface_pin={}
                    for key in tmpl_pin.keys():
                    for key in tmpl_pin.keys():
@@ -488,8 +498,8 @@ def set_mio_interfaces(mio_interfaces, options):
                            break;
                            break;
                    else:
                    else:
                        print 'Signal name '+individual_pin_name+' is not defined for interface '+iface_name+' in'
                        print 'Signal name '+individual_pin_name+' is not defined for interface '+iface_name+' in'
                        print conf_iface['CONFIG_NAME']+QULAIFIER_CHAR+individual_pin_name+" = "+option[individual_pin_name]
                        print conf_iface['CONFIG_NAME']+QUALIFIER_CHAR+individual_pin_name+" = "+option[individual_pin_name]
                        exit (ERR_NOSUCHSIGNAL)
                        exit (ERROR_DEFS['NOSUCHSIGNAL'])
                    if (value<0):
                    if (value<0):
                        try:
                        try:
                            del iface[individual_pin_name]
                            del iface[individual_pin_name]
@@ -501,9 +511,9 @@ def set_mio_interfaces(mio_interfaces, options):
                            value=tmpl_pin['PINS'][channel][0] # first variant
                            value=tmpl_pin['PINS'][channel][0] # first variant
                        if not value in tmpl_pin['PINS'][channel]:
                        if not value in tmpl_pin['PINS'][channel]:
                            print 'Invalid MIO pin number '+str(value)+' for interface '+iface_name+print_channel+', set in '
                            print 'Invalid MIO pin number '+str(value)+' for interface '+iface_name+print_channel+', set in '
                            print conf_iface['CONFIG_NAME']+QULAIFIER_CHAR+individual_pin_name+" = "+option[individual_pin_name]
                            print conf_iface['CONFIG_NAME']+QUALIFIER_CHAR+individual_pin_name+" = "+option[individual_pin_name]
                            print 'Allowed MIO pins are:',tmpl_pin['PINS'][channel]
                            print 'Allowed MIO pins are:',tmpl_pin['PINS'][channel]
                            exit (ERR_NOSUCHPIN)
                            exit (ERROR_DEFS['NOSUCHPIN'])
#set new pin data                            
#set new pin data                            
                        iface_pin={}
                        iface_pin={}
                        for key in tmpl_pin.keys():
                        for key in tmpl_pin.keys():
@@ -526,7 +536,7 @@ def config_name (iface, channel, signal):
    for mi in MIO_INTERFACES:
    for mi in MIO_INTERFACES:
        if (mi['IFACE']==iface) and (mi['CHANNEL']==channel) :
        if (mi['IFACE']==iface) and (mi['CHANNEL']==channel) :
            if signal:
            if signal:
                return mi['CONFIG_NAME']+QULAIFIER_CHAR+signal
                return mi['CONFIG_NAME']+QUALIFIER_CHAR+signal
            else:
            else:
                return mi['CONFIG_NAME']
                return mi['CONFIG_NAME']
                                  
                                  
@@ -551,7 +561,7 @@ def apply_mio_interfaces(mio, mio_interfaces,warn):
                    print config_name (name, channel, signal)+'=free'
                    print config_name (name, channel, signal)+'=free'
                    print 'to the board configuration file\n'
                    print 'to the board configuration file\n'
                if not warn:
                if not warn:
                    exit (ERR_MIOCONFLICT)
                    exit (ERROR_DEFS['MIOCONFLICT'])
            #add current pin usage information        
            #add current pin usage information        
            mio[pin['PIN']]['USED_IN'].append({'NAME':name, 'CHANNEL':channel,'SIGNAL':signal,'PRINT_CHANNEL':print_channel})
            mio[pin['PIN']]['USED_IN'].append({'NAME':name, 'CHANNEL':channel,'SIGNAL':signal,'PRINT_CHANNEL':print_channel})
            #modify mio pin attributes
            #modify mio pin attributes
@@ -627,7 +637,7 @@ def set_mio_attribs(mio,options):
                    key=int(option[len(prefix):])
                    key=int(option[len(prefix):])
                except:
                except:
                    print 'Invalid pin number ',option[len(prefix):],' in',option
                    print 'Invalid pin number ',option[len(prefix):],' in',option
                    exit (ERR_NOSUCHPIN)
                    exit (ERROR_DEFS['NOSUCHPIN)'])
                attribs[prefix][key]=options[option]
                attribs[prefix][key]=options[option]
                break
                break
#    print '------- attribs -----'
#    print '------- attribs -----'
@@ -642,7 +652,7 @@ def set_mio_attribs(mio,options):
#                    print '***',attr['PROPERTY'],pin,attr['VALUE']
#                    print '***',attr['PROPERTY'],pin,attr['VALUE']
                else:
                else:
                    print attr['PREFIX']+str(pin)+': pin number',pin,' out of range 0...53'
                    print attr['PREFIX']+str(pin)+': pin number',pin,' out of range 0...53'
                    exit (ERR_NOSUCHPIN) 
                    exit (ERROR_DEFS['NOSUCHPIN']) 
    #set IN, OUT, BIDIR (INOUT) parameters 
    #set IN, OUT, BIDIR (INOUT) parameters 
        elif ('SPECIAL' in attr) and (attr['SPECIAL']=='DIR') and (attr['PREFIX'] in attribs):
        elif ('SPECIAL' in attr) and (attr['SPECIAL']=='DIR') and (attr['PREFIX'] in attribs):
            for pin in attribs[attr['PREFIX']]:
            for pin in attribs[attr['PREFIX']]:
@@ -657,11 +667,11 @@ def set_mio_attribs(mio,options):
                else:
                else:
                    print 'Invalid MIO pin polarity in',attr['PREFIX']+str(pin),'=',value
                    print 'Invalid MIO pin polarity in',attr['PREFIX']+str(pin),'=',value
                    print 'Polarity can only be IN, OUT or BIDIR'
                    print 'Polarity can only be IN, OUT or BIDIR'
                    exit (ERR_INOUT)
                    exit (ERROR_DEFS['INOUT'])
                if (pin==7) or (pin==8) and (value!='OUT'):
                if (pin==7) or (pin==8) and (value!='OUT'):
                    print 'Invalid MIO pin polarity in',attr['PREFIX']+str(pin),'=',value
                    print 'Invalid MIO pin polarity in',attr['PREFIX']+str(pin),'=',value
                    print 'Polarity for MIO pins 7 and 8 can only be OUT'
                    print 'Polarity for MIO pins 7 and 8 can only be OUT'
                    exit (ERR_INOUT)
                    exit (ERROR_DEFS['INOUT'])
                mio[pin]['INOUT']=value #Where is it used?
                mio[pin]['INOUT']=value #Where is it used?
                if value=='IN':
                if value=='IN':
                    mio[pin]['TRISTATE']=True
                    mio[pin]['TRISTATE']=True
@@ -825,7 +835,7 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec):
    reserved0044=0;
    reserved0044=0;
    if 'CONFIG_EZYNQ_RESERVED44' in options: reserved0044= int(options['CONFIG_EZYNQ_RESERVED44'],0)
    if 'CONFIG_EZYNQ_RESERVED44' in options: reserved0044= int(options['CONFIG_EZYNQ_RESERVED44'],0)


    rfi_word=0xeafffffe #froma actual image
    rfi_word=0xeafffffe #from actual image
    waddr=0
    waddr=0
    for _ in range (0x20/4):
    for _ in range (0x20/4):
        image[waddr]=rfi_word # fill reserved for interrupts fields
        image[waddr]=rfi_word # fill reserved for interrupts fields
@@ -849,17 +859,17 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec):
    #ocm_offset
    #ocm_offset
    if ocm_offset<0x8c0:
    if ocm_offset<0x8c0:
        print 'Start offset should be >= 0x8c0, specified', hex(ocm_offset)
        print 'Start offset should be >= 0x8c0, specified', hex(ocm_offset)
        exit (ERR_HEAD)
        exit (ERROR_DEFS['HEAD'])
    elif (ocm_offset & 0x3f) != 0:
    elif (ocm_offset & 0x3f) != 0:
        print 'Start offset should be 64-bytes aligned, specified', hex(ocm_offset)
        print 'Start offset should be 64-bytes aligned, specified', hex(ocm_offset)
        exit (ERR_HEAD)
        exit (ERROR_DEFS['HEAD'])
    image[waddr]=ocm_offset # offset 0x30
    image[waddr]=ocm_offset # offset 0x30
    waddr+=1
    waddr+=1
       
       
    #ocm_len    
    #ocm_len    
    if ocm_len>0x30000:
    if ocm_len>0x30000:
        print 'Loaded to the OCM image should fit into 3 mapped pages of OCM - 192K (0x30000), specified ',hex(ocm_len)
        print 'Loaded to the OCM image should fit into 3 mapped pages of OCM - 192K (0x30000), specified ',hex(ocm_len)
        exit (ERR_HEAD)
        exit (ERROR_DEFS['HEAD'])
    image[waddr]=ocm_len # offset 0x34
    image[waddr]=ocm_len # offset 0x34
    waddr+=1
    waddr+=1


@@ -870,7 +880,7 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec):
    #start_exec    
    #start_exec    
    if (start_exec>0x30000) or (start_exec<0):
    if (start_exec>0x30000) or (start_exec<0):
        print 'Start address is relative to  OCM and should fit there - in 192K (0x30000), specified ',hex(start_exec)
        print 'Start address is relative to  OCM and should fit there - in 192K (0x30000), specified ',hex(start_exec)
        exit (ERR_HEAD)
        exit (ERROR_DEFS['HEAD'])
    image[waddr]=start_exec # offset 0x3c
    image[waddr]=start_exec # offset 0x3c
    waddr+=1
    waddr+=1
    
    
@@ -899,7 +909,7 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec):
    for register in registers:
    for register in registers:
        if not verify_register_accessible (register['ADDRESS']):
        if not verify_register_accessible (register['ADDRESS']):
            print 'Tried to set non-accessible register', hex(register['ADDRESS']),' with data ', hex(register['DATA'])
            print 'Tried to set non-accessible register', hex(register['ADDRESS']),' with data ', hex(register['DATA'])
            exit (ERR_NONACCESSIBLE_REHGISTER)
            exit (ERROR_DEFS['NONACCESSIBLE_REGISTER'])
        image[waddr]=register['ADDRESS']
        image[waddr]=register['ADDRESS']
        waddr+=1
        waddr+=1
        image[waddr]=register['DATA']
        image[waddr]=register['DATA']
@@ -928,7 +938,24 @@ def write_image(image,name):
    bf.close()
    bf.close()
         
         
#=========================
#=========================
options = parse_config(args.configs)
raw_configs=read_config(args.configs)

permit_undefined_bits=False
force=True #False
warn_notfit=True # False

ddr=ezynq_ddr.EzynqDDR(permit_undefined_bits, force, warn_notfit)
ddr.parse_raw_register_set(raw_configs,QUALIFIER_CHAR,force,warn_notfit)
#ddr.print_html_registers(html_file, show_bit_fields=True, show_comments=True)      
#class EzynqDDR:
#    def __init__(self,permit_undefined_bits=False,force=False,warn=False):
#    def parse_raw_register_set(self,raw_configs,qualifier_char,force=True,warn=True):
#    def print_html_registers(self, html_file, show_bit_fields=True, show_comments=True):




options = parse_config_mio(raw_configs)
if args.verbosity >= 3:
if args.verbosity >= 3:
    print options
    print options
if args.verbosity >= 1:
if args.verbosity >= 1:
@@ -945,7 +972,7 @@ set_mio_interfaces(mio_interfaces, options)
apply_mio_interfaces(mio, mio_interfaces,WARN)
apply_mio_interfaces(mio, mio_interfaces,WARN)
set_mio_attribs(mio,options)
set_mio_attribs(mio,options)
parse_mio(mio)
parse_mio(mio)
#sett MIO pin options and initial value for GPIO output
#set MIO pin options and initial value for GPIO output


if args.verbosity >= 1:
if args.verbosity >= 1:
    print '\n===== mio_interfaces === '
    print '\n===== mio_interfaces === '
@@ -971,6 +998,10 @@ else:
    f=False
    f=False
#output_slcr_lock(registers,f,False,MIO_HTML_MASK) #prohibited by RBL    
#output_slcr_lock(registers,f,False,MIO_HTML_MASK) #prohibited by RBL    
output_mio(registers,f,mio,MIO_HTML_MASK)
output_mio(registers,f,mio,MIO_HTML_MASK)

ddr.print_html_registers(f, MIO_HTML_MASK & 0x100, MIO_HTML_MASK & 0x200)      


#output_gpio_out(registers,f,MIO_HTML_MASK)        #prohibited by RBL
#output_gpio_out(registers,f,MIO_HTML_MASK)        #prohibited by RBL
#output_slcr_lock(registers,f,True,MIO_HTML_MASK)  #prohibited by RBL
#output_slcr_lock(registers,f,True,MIO_HTML_MASK)  #prohibited by RBL
if 'CONFIG_EZYNQ_UART_LOOPBACK_0' in options: uart_remote_loopback(registers,f, 0,MIO_HTML_MASK)
if 'CONFIG_EZYNQ_UART_LOOPBACK_0' in options: uart_remote_loopback(registers,f, 0,MIO_HTML_MASK)