
import os
import sys

appcust_path = os.path.abspath(os.path.join('..', 'src'))
sys.path.append(appcust_path)
template_path = "templates"
sys.path.append(template_path)

import register_class
import function_class
import helper_functions

class cPDOCurrentField(register_class.cScalingDMTerminator) :
    def __init__(self, register, iDict):
        register_class.cScalingDMTerminator.__init__(self, register, iDict)
        # map all strings representing units to scale factor
        self.dictScaleUnits = {'' : 0.01, 'A' : 0.01, 'mA' : 10.0}
        self.defaultUnit = 'A'


class cPDOVoltageField(register_class.cScalingDMTerminator) :
    def __init__(self, register, iDict):
        register_class.cScalingDMTerminator.__init__(self, register, iDict)
        # map all strings representing units to scale factor
        self.dictScaleUnits = {'' : 0.05, 'V' : 0.05, 'mV' : 50.0}
        self.defaultUnit = 'V'

class cPDOPowerField(register_class.cScalingDMTerminator) :
    def __init__(self, register, iDict):
        register_class.cScalingDMTerminator.__init__(self, register, iDict)
        # map all strings representing units to scale factor
        self.dictScaleUnits = {'' : 0.25, 'W' : 0.25, 'mW' : 250.0}
        self.defaultUnit = 'W'

class cOVPVoltageField(register_class.cScalingDMTerminator) :
    def __init__(self, register, iDict):
        register_class.cScalingDMTerminator.__init__(self, register, iDict)
        # map all strings representing units to scale factor
        self.dictScaleUnits = {'' : 0.32, 'V' : 0.32, 'mV' : 320.0}
        self.defaultUnit = 'V'
        self.scalingOffset = 12

class cI2CTimeoutField(register_class.cScalingDMTerminator) :
    def __init__(self, register, iDict):
        register_class.cScalingDMTerminator.__init__(self, register, iDict)
        # map all strings representing units to scale factor
        self.dictScaleUnits = {'' : 25.0, 'mS' : 25.0, 'S' : 0.025}
        self.defaultUnit = 'mS'
        self.scalingOffset = 1

class cAdjustableThresholdGPIO(register_class.cScalingDMTerminator) :
    def __init__(self, register, iDict):
        register_class.cScalingDMTerminator.__init__(self, register, iDict)
        # map all strings representing units to scale factor
        self.dictScaleUnits = {'' : 0.1, 'V' : 0.1}
        self.defaultUnit = 'V'

class cDMFixedSourcePdoArray(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)
        #
        self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Maximum Current',
                                                                'offset' : 0,
                                                                'bit length' : 10}))

        self.addChild(cPDOVoltageField( self.register,  { 'name' : 'Voltage',
                                                                'offset' : 10,
                                                                'bit length' : 10}))

        PeakCurrent = register_class.cListDMTerminator( self.register,  { 'name' : 'Peak Current',
                                                                'offset' : 20,
                                                                'bit length' : 2})
        PeakCurrent.help = """Set the percentage that the Source current can peak over the max before an OCP event occurs."""
        PeakCurrent.setReportList(['100%', '130%', '150%', '200%'])

        self.addChild(PeakCurrent)
        
        reserved = register_class.cForceSetDMTerminator( self.register,  { 'name' : "reserved",
                                                        'offset' : 22,
                                                        'bit length' : 8,
                                                        'force value' : int(0),
                                                        'force display' : 'reserved, set 0'})

        reserved.setFromInt(0)
        reserved.hide()
        self.addChild(reserved)

        supplyType = register_class.cListDMTerminator( self.register,  { 'name' : 'Supply Type',
                                                                'offset' : 30,
                                                                'bit length' : 2})
        supplyType.help = """Select what type of supply will source this PDO."""
        supplyType.setReportList(['Fixed Source', 'Battery Source', 'Variable Source'])
        supplyType.addUpdateRegisterByName("self")
        supplyType.setMaxValue(2)

        self.addChild(supplyType)


class cDMFixedSinkPdoArray(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)
        #
        self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Operating Current',
                                                                'offset' : 0,
                                                                'bit length' : 10}))

        self.addChild(cPDOVoltageField( self.register,  { 'name' : 'Voltage',
                                                                'offset' : 10,
                                                                'bit length' : 10}))

        PeakCurrent = register_class.cListDMTerminator( self.register,  { 'name' : 'Peak Current',
                                                                'offset' : 20,
                                                                'bit length' : 2})
        PeakCurrent.help = """Set the percentage that the Sink current can peak over the max before an OCP event occurs."""
        PeakCurrent.setReportList(['100%', '130%', '150%', '200%'])

        self.addChild(PeakCurrent)

        reserved = register_class.cForceSetDMTerminator( self.register,  { 'name' : "reserved",
                                                        'offset' : 22,
                                                        'bit length' : 8,
                                                        'force value' : int(0),
                                                        'force display' : 'reserved, set 0'})

        reserved.setFromInt(0)
        reserved.hide()
        self.addChild(reserved)

        supplyType = register_class.cListDMTerminator( self.register,  { 'name' : 'Supply Type',
                                                                'offset' : 30,
                                                                'bit length' : 2})
        supplyType.help = """Select what type of supply will be attached to this Sink PDO."""
        supplyType.setReportList(['Fixed Sink', 'Battery Sink', 'Variable Sink'])
        supplyType.addUpdateRegisterByName("self")
        supplyType.setMaxValue(2)

        self.addChild(supplyType)

        if ('No RDO Extensions' in iDict) and (iDict['No RDO Extensions'] == True) :
            pass
        else :
            self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Maximum Operating Current',
                                                                    'offset' : 224,
                                                                    'bit length' : 10}))

            self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Minimum Operating Current',
                                                                    'offset' : 234,
                                                                    'bit length' : 10}))

            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Ask For Max',
                                                                    'offset' : 254,
                                                                    'bit length' : 1}))



class cDMSourcePdo1Array(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        if ('Is Receive' in iDict) and (iDict['Is Receive'] == True) :
            isReceive = True
        else :
            isReceive = False

        self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Maximum Current',
                                                                'offset' : 0,
                                                                'bit length' : 10}))

        fvDisplayWidget = cPDOVoltageField( self.register,  { 'name' : 'Voltage',
                                                                'offset' : 10,
                                                                'bit length' : 10})


        fixedVoltage = register_class.cForceSetDMTerminator( self.register,  { 'name' : 'Voltage',
                                                                'offset' : 10,
                                                                'bit length' : 10,
                                                                'force value' : int(100),
                                                                'force display' : '5 V',
                                                                'display widget' : fvDisplayWidget })

        fixedVoltage.help = """Source PDO1 voltage will always be set to 5V to follow PD Spec."""
        self.addChild(fixedVoltage)
        fixedVoltage.setFromInt(100)

        PeakCurrent = register_class.cListDMTerminator( self.register,  { 'name' : 'Peak Current',
                                                                'offset' : 20,
                                                                'bit length' : 2})

        PeakCurrent.setReportList(['100%', '130%', '150%', '200%'])
        PeakCurrent.help = """Set the percentage that the Source current can peak over the max before an OCP event occurs."""
        self.addChild(PeakCurrent)


        reserved = register_class.cForceSetDMTerminator( self.register,  { 'name' : "reserved",
                                                        'offset' : 22,
                                                        'bit length' : 3,
                                                        'force value' : int(0),
                                                        'force display' : 'reserved, set 0'})

        reserved.setFromInt(0)
        reserved.hide()
        self.addChild(reserved)

        # Dual Role and Externally Powered are overwritten by firmware, so avoid confusion by not listing in GUI


        self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'USB Capable',
                                                                'offset' : 26,
                                                                'bit length' : 1}))


        self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'USB Suspend Supported',
                                                                'offset' : 28,
                                                                'bit length' : 1}))

        if ('Is Receive' in iDict ) and (iDict['Is Receive'] == True ) :
            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Dual Role Data',
                                                                    'offset' : 25,
                                                                    'bit length' : 1}))

            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Externally Powered',
                                                                    'offset' : 27,
                                                                    'bit length' : 1}))

            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Dual Role Power',
                                                                    'offset' : 29,
                                                                    'bit length' : 1}))


        supplyType = register_class.cListDMTerminator( self.register,  { 'name' : 'Supply Type',
                                                                'offset' : 30,
                                                                'bit length' : 2})
        supplyType.help = """Select what type of supply will source this PDO."""
        supplyType.setReportList(['Fixed Source', 'Battery Source', 'Variable Source'])
        supplyType.addUpdateRegisterByName("self")
        supplyType.setMaxValue(2)

        fixedSupplyType = register_class.cForceSetDMTerminator( self.register,  { 'name' : 'Supply Type',
                                                                'offset' : 30,
                                                                'bit length' : 2,
                                                                'force value' : int(0),
                                                                'force display' : 'Fixed Source',
                                                                'display widget' : supplyType })

        fixedSupplyType.help = """Supply Type for PDO0 may be Fixed, Battery, or Voltage and is compliant with the USB-PD specification."""
        self.addChild(fixedSupplyType)
        fixedSupplyType.setFromInt(0)


    def maxPower(self) :
        # 10 mA steps
        current = self.getChildByName('Maximum Current').valueToInt()
        # 50 mV steps
        voltage = self.getChildByName('Voltage').valueToInt()
        # 0.01 * 0.05 = .0005 Watts
        power = current * voltage * 0.0005

        return power

class cDMSinkPdo1Array(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        if ('Is Receive' in iDict) and (iDict['Is Receive'] == True) :
            isReceive = True
        else :
            isReceive = False

        self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Operating Current',
                                                                'offset' : 0,
                                                                'bit length' : 10}))

        fvDisplayWidget = cPDOVoltageField( self.register,  { 'name' : 'Voltage',
                                                                'offset' : 10,
                                                                'bit length' : 10})


        fixedVoltage = register_class.cForceSetDMTerminator( self.register,  { 'name' : 'Voltage',
                                                                'offset' : 10,
                                                                'bit length' : 10,
                                                                'force value' : int(100),
                                                                'force display' : '5 V',
                                                                'display widget' : fvDisplayWidget })

        fixedVoltage.help = """Sink PDO1 will always be 5V to be PD Spec compliant."""
        self.addChild(fixedVoltage)
        fixedVoltage.setFromInt(100)

        PeakCurrent = register_class.cListDMTerminator( self.register,  { 'name' : 'Peak Current',
                                                                'offset' : 20,
                                                                'bit length' : 2})
        PeakCurrent.help = """Set the percentage that the Sink current can peak over the max before an OCP event occurs."""
        PeakCurrent.setReportList(['100%', '130%', '150%', '200%'])

        self.addChild(PeakCurrent)

        reserved = register_class.cForceSetDMTerminator( self.register,  { 'name' : "reserved",
                                                        'offset' : 22,
                                                        'bit length' : 3,
                                                        'force value' : int(0),
                                                        'force display' : 'reserved, set 0'})

        reserved.setFromInt(0)
        reserved.hide()
        self.addChild(reserved)

        # Dual Role and Externally Powered are overwritten by firmware, so avoid confusion by not listing in GUI
        # USB capable is set in autonegotiate sink register
        # Higher Capability is set automatically if there are any >5V contracts

        if ('Is Receive' in iDict ) and (iDict['Is Receive'] == True ) :
            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Dual Role Data',
                                                                    'offset' : 25,
                                                                    'bit length' : 1}))

            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'USB Capable',
                                                                    'offset' : 26,
                                                                    'bit length' : 1}))

            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Externally Powered',
                                                                    'offset' : 27,
                                                                    'bit length' : 1}))

            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Higher Capability',
                                                                    'offset' : 28,
                                                                    'bit length' : 1}))

            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Dual Role Power',
                                                                    'offset' : 29,
                                                                    'bit length' : 1}))

        supplyType = register_class.cListDMTerminator( self.register,  { 'name' : 'Supply Type',
                                                                'offset' : 30,
                                                                'bit length' : 2})
        supplyType.help = """Select what type of supply this PDO will sink."""
        supplyType.setReportList(['Fixed Sink', 'Battery Sink', 'Variable Sink'])
        supplyType.addUpdateRegisterByName("self")
        supplyType.setMaxValue(2)

        fixedSupplyType = register_class.cForceSetDMTerminator( self.register,  { 'name' : 'Supply Type',
                                                                'offset' : 30,
                                                                'bit length' : 2,
                                                                'force value' : int(0),
                                                                'force display' : 'Fixed Sink',
                                                                'display widget' : supplyType })

        fixedSupplyType.help = """Supply Type that will source PDO1."""
        self.addChild(fixedSupplyType)
        fixedSupplyType.setFromInt(0)


        if (('No RDO Extensions' in iDict) and (iDict['No RDO Extensions'] == True)) or (('Is Receive' in iDict) and (iDict['Is Receive'] == True)) :
            pass
        else :
            self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Maximum Operating Current',
                                                                    'offset' : 224,
                                                                    'bit length' : 10}))

            self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Minimum Operating Current',
                                                                    'offset' : 234,
                                                                    'bit length' : 10}))

            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Ask For Max',
                                                                    'offset' : 254,
                                                                    'bit length' : 1}))




class cDMVariableSourcePdoArray(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)
        #
        self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Maximum Current',
                                                                'offset' : 0,
                                                                'bit length' : 10}))

        self.addChild(cPDOVoltageField( self.register,  { 'name' : 'Minimum Voltage',
                                                                'offset' : 10,
                                                                'bit length' : 10}))

        self.addChild(cPDOVoltageField( self.register,  { 'name' : 'Maximum Voltage',
                                                                'offset' : 20,
                                                                'bit length' : 10}))

        supplyType = register_class.cListDMTerminator( self.register,  { 'name' : 'Supply Type',
                                                                'offset' : 30,
                                                                'bit length' : 2})
        supplyType.help = """Supply Type that will Source this PDO."""
        supplyType.setReportList(['Fixed Source', 'Battery Source', 'Variable Source'])
        supplyType.addUpdateRegisterByName("self")
        supplyType.setMaxValue(2)

        self.addChild(supplyType)


class cDMVariableSinkPdoArray(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)
        #
        self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Operating Current',
                                                                'offset' : 0,
                                                                'bit length' : 10}))

        self.addChild(cPDOVoltageField( self.register,  { 'name' : 'Minimum Voltage',
                                                                'offset' : 10,
                                                                'bit length' : 10}))

        self.addChild(cPDOVoltageField( self.register,  { 'name' : 'Maximum Voltage',
                                                                'offset' : 20,
                                                                'bit length' : 10}))

        supplyType = register_class.cListDMTerminator( self.register,  { 'name' : 'Supply Type',
                                                                'offset' : 30,
                                                                'bit length' : 2})
        supplyType.help = """Supply Type that will be used for this Sink PDO."""
        supplyType.setReportList(['Fixed Sink', 'Battery Sink', 'Variable Sink'])
        supplyType.addUpdateRegisterByName("self")
        supplyType.setMaxValue(2)

        self.addChild(supplyType)


        if ('No RDO Extensions' in iDict) and (iDict['No RDO Extensions'] == True) :
            pass
        else :
            self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Maximum Operating Current',
                                                                    'offset' : 224,
                                                                    'bit length' : 10}))

            self.addChild(cPDOCurrentField( self.register,  { 'name' : 'Minimum Operating Current',
                                                                    'offset' : 234,
                                                                    'bit length' : 10}))

            self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Ask For Max',
                                                                    'offset' : 254,
                                                                    'bit length' : 1}))



class cDMBatterySourcePdoArray(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)
        #
        self.addChild(cPDOPowerField( self.register,  { 'name' : 'Maximum Power',
                                                                'offset' : 0,
                                                                'bit length' : 10}))

        self.addChild(cPDOVoltageField( self.register,  { 'name' : 'Minimum Voltage',
                                                                'offset' : 10,
                                                                'bit length' : 10}))

        self.addChild(cPDOVoltageField( self.register,  { 'name' : 'Maximum Voltage',
                                                                'offset' : 20,
                                                                'bit length' : 10}))

        supplyType = register_class.cListDMTerminator( self.register,  { 'name' : 'Supply Type',
                                                                'offset' : 30,
                                                                'bit length' : 2})
        supplyType.help = """Supply type that will source this PDO."""
        supplyType.setReportList(['Fixed Source', 'Battery Source', 'Variable Source'])
        supplyType.addUpdateRegisterByName("self")
        supplyType.setMaxValue(2)

        self.addChild(supplyType)


class cDMBatterySinkPdoArray(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)
        #
        self.addChild(cPDOPowerField( self.register,  { 'name' : 'Operating Power',
                                                                'offset' : 0,
                                                                'bit length' : 10}))

        self.addChild(cPDOVoltageField( self.register,  { 'name' : 'Minimum Voltage',
                                                                'offset' : 10,
                                                                'bit length' : 10}))

        self.addChild(cPDOVoltageField( self.register,  { 'name' : 'Maximum Voltage',
                                                                'offset' : 20,
                                                                'bit length' : 10}))

        supplyType = register_class.cListDMTerminator( self.register,  { 'name' : 'Supply Type',
                                                                'offset' : 30,
                                                                'bit length' : 2})
        supplyType.help = """Supply Type that will be used for this Sink PDO."""
        supplyType.setReportList(['Fixed Sink', 'Battery Sink', 'Variable Sink'])
        supplyType.addUpdateRegisterByName("self")
        supplyType.setMaxValue(2)

        self.addChild(supplyType)

        self.addChild(cPDOPowerField( self.register,  { 'name' : 'Maximum Operating Power',
                                                                'offset' : 224,
                                                                'bit length' : 10}))

        self.addChild(cPDOPowerField( self.register,  { 'name' : 'Minimum Operating Power',
                                                                'offset' : 234,
                                                                'bit length' : 10}))

        self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Ask For Max',
                                                                'offset' : 254,
                                                                'bit length' : 1}))



# TODO : This is a common need. Build an extender class that takes an arbitrary data model in init and adds the
#        prepend and append capability.
class cDMAnySourcePdoArray(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        self.prependChildrenArray = []
        self.appendChildrenArray = []

        self.fixedOverlay = cDMFixedSourcePdoArray(register, self.tier, iDict)
        self.variableOverlay = cDMVariableSourcePdoArray(register, self.tier, iDict)
        self.batteryOverlay = cDMBatterySourcePdoArray(register, self.tier, iDict)

        # self.dataModelChildrenArray must contain the children in all three of the overlays
        self.dataModelChildrenArray = []
        self.dataModelChildrenArray.extend(self.fixedOverlay.dataModelChildrenArray)
        self.dataModelChildrenArray.extend(self.variableOverlay.dataModelChildrenArray)
        self.dataModelChildrenArray.extend(self.batteryOverlay.dataModelChildrenArray)

        self.dataModelGenerator = self.AnyPdoArrayDMGenerator

    def findDependentRegisters(self):
        # only update forcevals in current overlay
        type = self.fixedOverlay.getChildByName('Supply Type').valueToInt()
        if type == 0 :
            return self.fixedOverlay.findDependentRegisters() 
            
        elif type == 1 :
            return self.variableOverlay.findDependentRegisters() 

        elif type == 2:
            return self.batteryOverlay.findDependentRegisters() 

    def updateForceVal(self):
        # todo: should make a set parent call instead of allowing to be set directly
        #       then the objects can correctly set sub-object parent relationships
        self.fixedOverlay.parent = self.parent
        self.variableOverlay.parent = self.parent
        self.batteryOverlay.parent = self.parent

        # only update forcevals in current overlay
        type = self.fixedOverlay.getChildByName('Supply Type').valueToInt()
        if type == 0 :
            self.fixedOverlay.updateForceVal() 
            
        elif type == 1 :
            self.variableOverlay.updateForceVal() 

        elif type == 2:
            self.batteryOverlay.updateForceVal() 

    def maxPower(self) :
        power = 0.0
        type = self.fixedOverlay.getChildByName('Supply Type').valueToInt()
        if type == 0 :
            # 10 mA steps
            current = self.fixedOverlay.getChildByName('Maximum Current').valueToInt()
            # 50 mV steps
            voltage = self.fixedOverlay.getChildByName('Voltage').valueToInt()
            # 0.01 * 0.05 = .0005 Watts
            power = current * voltage * 0.0005

        if type == 1 :
            # 10 mA steps
            current = self.variableOverlay.getChildByName('Maximum Current').valueToInt()
            # 50 mV steps
            voltage = self.variableOverlay.getChildByName('Maximum Voltage').valueToInt()
            # 0.01 * 0.05 = .0005 Watts
            power = current * voltage * 0.0005

        if type == 2 :
            # reported in 250 mW steps
            power = self.batteryOverlay.getChildByName('Maximum Power').valueToInt() * 0.25

        return power

    def prependChild(self, child):
        self.prependChildrenArray[:0] = [child,]
        # it is okay to append to the dataModelChildrenArray because it is not directly used in the
        #    data model generator.
        self.dataModelChildrenArray.append(child)

    def addChild(self, child):
        child.parent = self
        self.appendChildrenArray.append(child)
        self.dataModelChildrenArray.append(child)

    # return the first child with a matching name or none if no match
    def getChildByName(self, name):
        for child in self.prependChildrenArray :
            if child.name == name :
                return child

        for child in self.appendChildrenArray :
            if child.name == name :
                return child

        type = self.fixedOverlay.getChildByName('Supply Type').valueToInt()
        if type == 0 :
            for child in self.fixedOverlay :
                if child.name == name :
                    return child
        elif type == 1 :
            for child in self.variableOverlay :
                if child.name == name :
                    return child
        elif type == 2:
            for child in self.batteryOverlay :
                if child.name == name :
                    return child

        return None

    def AnyPdoArrayDMGenerator(self):
        # todo: should make a set parent call instead of allowing to be set directly
        #       then the objects can correctly set sub-object parent relationships
        self.fixedOverlay.parent = self.parent
        self.variableOverlay.parent = self.parent
        self.batteryOverlay.parent = self.parent

        type = self.fixedOverlay.getChildByName('Supply Type').valueToInt()
        retDict = {'name' : self.name, 'grouping tier' : self.tier, 'show' : self.show, 'data model list' : []}
        if type == 0 :
            for child in self.prependChildrenArray :
                if isinstance(child, dict) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
            retDict['data model list'].extend(self.fixedOverlay.dataModelGenerator()['data model list'])
            for child in self.appendChildrenArray :
                if isinstance(child, list) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
        elif type == 1:
            for child in self.prependChildrenArray :
                if isinstance(child, list) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
            retDict['data model list'].extend(self.batteryOverlay.dataModelGenerator()['data model list'])
            for child in self.appendChildrenArray :
                if isinstance(child, list) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
        elif type == 2 :
            for child in self.prependChildrenArray :
                if isinstance(child, list) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
            retDict['data model list'].extend(self.variableOverlay.dataModelGenerator()['data model list'])
            for child in self.appendChildrenArray :
                if isinstance(child, list) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
        else :
            # invalid setting
            # TODO: improve error handling
            retDict['data model list'] = []

        return retDict


class cDMAnySinkPdoArray(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        self.prependChildrenArray = []
        self.appendChildrenArray = []

        self.fixedOverlay = cDMFixedSinkPdoArray(register, self.tier, iDict)
        self.variableOverlay = cDMVariableSinkPdoArray(register, self.tier, iDict)
        self.batteryOverlay = cDMBatterySinkPdoArray(register, self.tier, iDict)

        # self.dataModelChildrenArray must contain the children in all three of the overlays
        self.dataModelChildrenArray = []
        self.dataModelChildrenArray.extend(self.fixedOverlay.dataModelChildrenArray)
        self.dataModelChildrenArray.extend(self.variableOverlay.dataModelChildrenArray)
        self.dataModelChildrenArray.extend(self.batteryOverlay.dataModelChildrenArray)

        self.dataModelGenerator = self.AnyPdoArrayDMGenerator

    def findDependentRegisters(self):
        # only update forcevals in current overlay
        type = self.fixedOverlay.getChildByName('Supply Type').valueToInt()
        if type == 0 :
            return self.fixedOverlay.findDependentRegisters() 
            
        elif type == 1 :
            return self.variableOverlay.findDependentRegisters() 

        elif type == 2:
            return self.batteryOverlay.findDependentRegisters() 

    def updateForceVal(self):
        # todo: should make a set parent call instead of allowing to be set directly
        #       then the objects can correctly set sub-object parent relationships
        self.fixedOverlay.parent = self.parent
        self.variableOverlay.parent = self.parent
        self.batteryOverlay.parent = self.parent

        # only update forcevals in current overlay
        type = self.fixedOverlay.getChildByName('Supply Type').valueToInt()
        if type == 0 :
            self.fixedOverlay.updateForceVal() 
            
        elif type == 1 :
            self.variableOverlay.updateForceVal() 

        elif type == 2:
            self.batteryOverlay.updateForceVal() 

    def prependChild(self, child):
        self.prependChildrenArray[:0] = [child,]
        # it is okay to append to the dataModelChildrenArray because it is not directly used in the
        #    data model generator.
        self.dataModelChildrenArray.append(child)

    def addChild(self, child):
        child.parent = self
        self.appendChildrenArray.append(child)
        self.dataModelChildrenArray.append(child)

    # return the first child with a matching name or none if no match
    def getChildByName(self, name):
        for child in self.prependChildrenArray :
            if child.name == name :
                return child

        for child in self.appendChildrenArray :
            if child.name == name :
                return child

        type = self.fixedOverlay.getChildByName('Supply Type').valueToInt()
        if type == 0 :
            for child in self.fixedOverlay :
                if child.name == name :
                    return child
        elif type == 1 :
            for child in self.variableOverlay :
                if child.name == name :
                    return child
        elif type == 2:
            for child in self.batteryOverlay :
                if child.name == name :
                    return child

        return None

    def AnyPdoArrayDMGenerator(self):
        # todo: should make a set parent call instead of allowing to be set directly
        #       then the objects can correctly set sub-object parent relationships
        self.fixedOverlay.parent = self.parent
        self.variableOverlay.parent = self.parent
        self.batteryOverlay.parent = self.parent

        type = self.fixedOverlay.getChildByName('Supply Type').valueToInt()
        retDict = {'name' : self.name, 'grouping tier' : self.tier, 'show' : self.show, 'data model list' : []}
        if type == 0 :
            for child in self.prependChildrenArray :
                if isinstance(child, dict) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
            retDict['data model list'].extend(self.fixedOverlay.dataModelGenerator()['data model list'])
            for child in self.appendChildrenArray :
                if isinstance(child, list) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
        elif type == 1:
            for child in self.prependChildrenArray :
                if isinstance(child, list) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
            retDict['data model list'].extend(self.batteryOverlay.dataModelGenerator()['data model list'])
            for child in self.appendChildrenArray :
                if isinstance(child, list) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
        elif type == 2 :
            for child in self.prependChildrenArray :
                if isinstance(child, list) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
            retDict['data model list'].extend(self.variableOverlay.dataModelGenerator()['data model list'])
            for child in self.appendChildrenArray :
                if isinstance(child, list) :
                    retDict['data model list'].extend(child.dataModelGenerator()['data model list'])
                else :
                    retDict['data model list'].append(child.dataModelGenerator())
        else :
            # invalid setting
            # TODO: improve error handling
            retDict['data model list'] = []

        return retDict


class cUFPIDHeaderVDO(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)
        #
        self.addChild(register_class.cHexDMTerminator( self.register,  { 'name' : 'USB Vendor ID',
                                                                'offset' : 0,
                                                                'bit length' : 16}))

        self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Modal Operation Supported',
                                                                'offset' : 26,
                                                                'bit length' : 1}))

        productType = register_class.cListDMTerminator( self.register,  { 'name' : 'Product Type',
                                                                'offset' : 27,
                                                                'bit length' : 3})
        productType.setMaxValue(6)
        productType.setReportList(['Undefined', 'Hub', 'Peripheral', 'Passive Cable', 'Active Cable', 'Alternate Mode Adapter', 'Power Brick'])

        self.addChild(productType)

        self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Data Capable as USB Device',
                                                                'offset' : 30,
                                                                'bit length' : 1}))

        self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'Data Capable as USB Host',
                                                                'offset' : 31,
                                                                'bit length' : 1}))


class cUFPProductVDO(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)
        #
        self.addChild(register_class.cHexDMTerminator( self.register,  { 'name' : 'BCD Device',
                                                                'offset' : 0,
                                                                'bit length' : 16}))

        self.addChild(register_class.cHexDMTerminator( self.register,  { 'name' : 'USB Product ID',
                                                                'offset' : 16,
                                                                'bit length' : 16}))


class cCableVDO(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)
        #
        usbSSSignal = register_class.cListDMTerminator( self.register,  { 'name' : 'USB SS Signalling',
                                                                'offset' : 0,
                                                                'bit length' : 3})
        usbSSSignal.setMaxValue(2)
        usbSSSignal.setReportList(['USB 2.0 Only', 'USB 3.1 Gen 1', 'USB 3.1 Gen 1 and 2'])

        self.addChild(usbSSSignal)

        self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'SOP" Controller Present',
                                                                'offset' : 3,
                                                                'bit length' : 1}))

        self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'VBus Through Cable',
                                                                'offset' : 4,
                                                                'bit length' : 1}))

        currentCap = register_class.cListDMTerminator( self.register,  { 'name' : 'VBus Current Capability',
                                                                'offset' : 5,
                                                                'bit length' : 2})
        currentCap.setMaxValue(3)
        currentCap.setReportList(['1.5 A', '3.0 A', '5 A'])

        self.addChild(currentCap)

        ssrx2dir = register_class.cListDMTerminator( self.register,  { 'name' : 'SSRx 2 Directionality',
                                                                'offset' : 7,
                                                                'bit length' : 1})
        ssrx2dir.setReportList(['Fixed', 'Configurable'])

        self.addChild(ssrx2dir)

        ssrx1dir = register_class.cListDMTerminator( self.register,  { 'name' : 'SSRx 1 Directionality',
                                                                'offset' : 8,
                                                                'bit length' : 1})
        ssrx1dir.setReportList(['Fixed', 'Configurable'])

        self.addChild(ssrx1dir)

        sstx2dir = register_class.cListDMTerminator( self.register,  { 'name' : 'SSTx 2 Directionality',
                                                                'offset' : 9,
                                                                'bit length' : 1})
        sstx2dir.setReportList(['Fixed', 'Configurable'])

        self.addChild(sstx2dir)

        sstx1dir = register_class.cListDMTerminator( self.register,  { 'name' : 'SSTx 1 Directionality',
                                                                'offset' : 10,
                                                                'bit length' : 1})
        sstx1dir.setReportList(['Fixed', 'Configurable'])

        self.addChild(sstx1dir)

        cableTerm = register_class.cListDMTerminator( self.register,  { 'name' : 'Cable Termination Type',
                                                                'offset' : 11,
                                                                'bit length' : 2})
        cableTerm.setReportList(['Both Ends Passive, VConn Not Required', 'Both Ends Passive, VConn Is Required', 'One End Active, One End Passive, VConn Is Required', 'Both Ends Active, VConn Is Required'])

        self.addChild(cableTerm)

        cableLat = register_class.cListDMTerminator( self.register,  { 'name' : 'Cable Latency',
                                                                'offset' : 13,
                                                                'bit length' : 4})

        cableLat.setMaxValue(10)
        cableLat.setReportList(['reserved (0000b)', '< 10nS (~1m)', '10-20nS (~2m)', '20-30nS (~3m)', '30-40nS (~4m)', '40-50nS (~5m)', '50-60nS (~6m)', '60-70nS (~7m)', '1000nS (~100m)', '2000nS (~200m)', '3000nS (~300m)'])

        self.addChild(cableLat)

        plugRec = register_class.cListDMTerminator( self.register,  { 'name' : 'Type-C Plug/Receptacle',
                                                                'offset' : 17,
                                                                'bit length' : 1})

        plugRec.setMaxValue(10)
        plugRec.setReportList(['Plug', 'Receptacle'])

        self.addChild(plugRec)

        typeCto = register_class.cListDMTerminator( self.register,  { 'name' : 'Type-C to Type-A/B/C',
                                                                'offset' : 18,
                                                                'bit length' : 2})

        typeCto.setMaxValue(2)
        typeCto.setReportList(['Type-A', 'Type-B', 'Type-C'])

        self.addChild(typeCto)

        self.addChild(register_class.cHexDMTerminator( self.register,  { 'name' : 'Cable Firmware Version',
                                                                'offset' : 24,
                                                                'bit length' : 4}))

        self.addChild(register_class.cHexDMTerminator( self.register,  { 'name' : 'Cable Hardware Version',
                                                                'offset' : 28,
                                                                'bit length' : 4}))


class cAMAVDO(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)
        #
        usbSSSignal = register_class.cListDMTerminator( self.register,  { 'name' : 'USB SS Signalling',
                                                                'offset' : 0,
                                                                'bit length' : 3})
        usbSSSignal.setMaxValue(3)
        usbSSSignal.setReportList(['USB 2.0 Only', 'USB 3.1 Gen 1', 'USB 3.1 Gen 1 and 2', 'USB 2.0 Billboard Only'])

        self.addChild(usbSSSignal)

        self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'VBus Required',
                                                                'offset' : 3,
                                                                'bit length' : 1}))

        self.addChild(register_class.cBooleanDMTerminator( self.register,  { 'name' : 'VConn Required',
                                                                'offset' : 4,
                                                                'bit length' : 1}))

        vConnPower = register_class.cListDMTerminator( self.register,  { 'name' : 'VConn Power',
                                                                'offset' : 5,
                                                                'bit length' : 3})
        vConnPower.setMaxValue(6)
        vConnPower.setReportList(['1 W', '1.5 W', '2 W', '3 W', '4 W', '5 W', '6 W'])

        self.addChild(vConnPower)

        ssrx2dir = register_class.cListDMTerminator( self.register,  { 'name' : 'SSRx 2 Directionality',
                                                                'offset' : 8,
                                                                'bit length' : 1})
        ssrx2dir.setReportList(['Fixed', 'Configurable'])

        self.addChild(ssrx2dir)

        ssrx1dir = register_class.cListDMTerminator( self.register,  { 'name' : 'SSRx 1 Directionality',
                                                                'offset' : 9,
                                                                'bit length' : 1})
        ssrx1dir.setReportList(['Fixed', 'Configurable'])

        self.addChild(ssrx1dir)

        sstx2dir = register_class.cListDMTerminator( self.register,  { 'name' : 'SSTx 2 Directionality',
                                                                'offset' : 10,
                                                                'bit length' : 1})
        sstx2dir.setReportList(['Fixed', 'Configurable'])

        self.addChild(sstx2dir)

        sstx1dir = register_class.cListDMTerminator( self.register,  { 'name' : 'SSTx 1 Directionality',
                                                                'offset' : 11,
                                                                'bit length' : 1})
        sstx1dir.setReportList(['Fixed', 'Configurable'])

        self.addChild(sstx1dir)

        self.addChild(register_class.cHexDMTerminator( self.register,  { 'name' : 'AMA Firmware Version',
                                                                'offset' : 24,
                                                                'bit length' : 4}))

        self.addChild(register_class.cHexDMTerminator( self.register,  { 'name' : 'AMA Hardware Version',
                                                                'offset' : 28,
                                                                'bit length' : 4}))



#==========================================================================
# main registers
#==========================================================================

class cProtoVer_0x02_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Protocol Version',
                                                 'address' : 0x02,
                                                 'byte length' : 4,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Protocol Version',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        tbtVer = register_class.cForceSetDMTerminator( self,  { 'name' : 'Thunderbolt(TM) Protocol Version',
                                                                'offset' : 0,
                                                                'bit length' : 32,
                                                                'force value' : int(1),
                                                                'force display' : '1'})

        self.dataModel.addChild(tbtVer)
        tbtVer.setFromInt(1)


class cMode_0x03_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Mode',
                                                 'address' : 0x03,
                                                 'byte length' : 4,
                                                 'permission' : 'DRO'})

        self.setAsShared()

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Mode',
                                                        'offset' : 0,
                                                        'bit length' : 32 })
        mode = register_class.cAsciiDMTerminator(self,
                                                        {'name' : 'Mode',
                                                         'offset' : 0,
                                                         'bit length' : 32 })
        mode.help = """4-character string to indicate mode of device"""
        self.dataModel.addChild(mode)


class cCustUse_0x06_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Customer Use',
                                                 'address' : 0x06,
                                                 'byte length' : 8,
                                                 'permission' : 'RO'})

        self.setAsShared()

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Customer Use',
                                                        'offset' : 0,
                                                        'bit length' : 64 })

        svid = register_class.cHexDMTerminator(self,
                                                      {'name' : 'Customer Use Word 1',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        svid.help = """The customer use register is a read-only register that is configured at build time using the configuration tool. It stores an arbitrary value that may be read from the customer use register (0x06) at run time.

Common uses of this register include platform identifiers, configuration version numbers and date codes."""

        self.dataModel.addChild(svid)

        svid = register_class.cHexDMTerminator(self,
                                                      {'name' : 'Customer Use Word 2',
                                                        'offset' : 32,
                                                        'bit length' : 32 })

        svid.help = """The customer use register is a read-only register that is configured at build time using the configuration tool. It stores an arbitrary value that may be read from the customer use register (0x06) at run time.

Common uses of this register include platform identifiers, configuration version numbers and date codes."""

        self.dataModel.addChild(svid)


class cVersion_0x0f_register(register_class.cRegister):
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Version',
                                                 'address' : 0x0f,
                                                 'byte length' : 4,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Version',
                                                        'offset' : 0,
                                                        'bit length' : 32 })


        versionData = register_class.cHexDMTerminator(self,
                                                                    {'name' : 'Version',
                                                                     'offset' : 0,
                                                                     'bit length' : 32 })
        versionData.help = """Binary Coded Decimal version number, bootloader/application code version. Represented as VVVV.MM.RR with leading 0's removed \
                                \n\ne.g. 65794d (decimal) -> 0x00010102 -> 0001.01.02 -> 1.1.2 (version). The version information is returned in little Endian format i.e. byte 1 = RR, byte 2 = MM, etc. """
        self.dataModel.addChild(versionData)


class cIntMask1_0x16_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Interrupt Mask for I2C1',
                                                 'address' : 0x16,
                                                 'byte length' : 8,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Interrupt Mask for I2C1',
                                                        'offset' : 0,
                                                        'bit length' : 64 })

        SoftReset = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Soft Reset',
                                                                     'offset' : 0,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(SoftReset)

        HardReset = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Hard Reset',
                                                                     'offset' : 1,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(HardReset)

        PowerPathEvent = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Power Path Event',
                                                                     'offset' : 2,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PowerPathEvent)

        PlugInsertOrRemoval = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Plug Insert or Removal',
                                                                     'offset' : 3,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PlugInsertOrRemoval)

        PRSwapComplete = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'PR Swap Complete',
                                                                     'offset' : 4,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PRSwapComplete)

        DRSwapComplete = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'DR Swap Complete',
                                                                     'offset' : 5,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(DRSwapComplete)

        AwokenByHost = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Awoken by Host',
                                                                     'offset' : 6,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(AwokenByHost)

        RdoReceivedFromSink = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'RDO Received from Sink',
                                                                     'offset' : 7,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(RdoReceivedFromSink)

        Bist = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Built-In Self Test',
                                                                     'offset' : 8,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Bist)

        Overcurrent = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Overcurrent Event',
                                                                     'offset' : 9,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Overcurrent)

        AttentionReceived = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Attention Received',
                                                                     'offset' : 10,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(AttentionReceived)

        VDMReceived = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Vendor-Defined Message Received',
                                                                     'offset' : 11,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(VDMReceived)

        NewContractAsCons = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'New Contract as Consumer',
                                                                     'offset' : 12,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(NewContractAsCons)

        NewContractAsProv = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'New Contract as Provider',
                                                                     'offset' : 13,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(NewContractAsProv)

        SourceCapMsgReady = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Source Capabilities Message Ready',
                                                                     'offset' : 14,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(SourceCapMsgReady)

        SinkCapMsgReady = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Sink Capabilities Message Ready',
                                                                     'offset' : 15,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(SinkCapMsgReady)

        SwapRequested = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Swap Requested',
                                                                     'offset' : 17,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(SwapRequested)

        BISTMessageIgnored = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'BIST Message Ignored',
                                                                     'offset' : 18,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(BISTMessageIgnored)

        GotoMinReceived = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'GotoMin Received',
                                                                     'offset' : 19,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(GotoMinReceived)

        UsbHostPresent = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'USB Host Present',
                                                                     'offset' : 20,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UsbHostPresent)

        UsbHostPresentNoLonger = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'USB Host Present No Longer',
                                                                     'offset' : 21,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UsbHostPresentNoLonger)

        HighVoltageWarning = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'High Voltage Warning',
                                                                     'offset' : 22,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(HighVoltageWarning)

        PPswitchChanged = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Power Path Switch Changed',
                                                                     'offset' : 23,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PPswitchChanged)

        PowerStatusUpdate = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Power Status Update',
                                                                     'offset' : 24,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PowerStatusUpdate)

        DataStatusUpdate = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Data Status Update',
                                                                     'offset' : 25,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(DataStatusUpdate)

        StatusUpdate = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Status Update',
                                                                     'offset' : 26,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(StatusUpdate)

        PDStatusUpdate = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'PD Status Update',
                                                                     'offset' : 27,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PDStatusUpdate)

        ADCLowThreshold = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'ADC Low Threshold',
                                                                     'offset' : 28,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(ADCLowThreshold)

        ADCHighThreshold = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'ADC High Threshold',
                                                                     'offset' : 29,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(ADCHighThreshold)

        Cmd1Complete = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'CMD1 Complete',
                                                                     'offset' : 30,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Cmd1Complete)

        Cmd2Complete = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'CMD2 Complete',
                                                                     'offset' : 31,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Cmd2Complete)

        Error_DeviceIncompatible = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Device Incompatible',
                                                                     'offset' : 32,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_DeviceIncompatible)

        Error_CannotProvideVoltageOrCurrent = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Cannot Provide Voltage or Current',
                                                                     'offset' : 33,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_CannotProvideVoltageOrCurrent)

        Error_CanProvideVoltageOrCurrentLater = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Cannot Provide Voltage or Current Later',
                                                                     'offset' : 34,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_CanProvideVoltageOrCurrentLater)

        Error_PowerEventOccurred = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Power Event Occurred',
                                                                     'offset' : 35,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_PowerEventOccurred)

        Error_MissingGetCapMessage = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Missing Get Capabilities Message',
                                                                     'offset' : 36,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_MissingGetCapMessage)

        Error_ProtocolError = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Protocol Error',
                                                                     'offset' : 38,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_ProtocolError)

        Error_MessageData = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Message Data',
                                                                     'offset' : 39,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_MessageData)

        Error_DischargeFailed = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Discharge Failed',
                                                                     'offset' : 41,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_DischargeFailed)

        SnkTransitionComplete = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Sink Transition Complete',
                                                                     'offset' : 42,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(SnkTransitionComplete)

        Error_UnableToSource = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Unable to Source',
                                                                     'offset' : 46,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_UnableToSource)

        UserSvidModeEntered = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'User SVID Mode Entered',
                                                                     'offset' : 56,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UserSvidModeEntered)

        UserSvidModeExited = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'User SVID Mode Exited',
                                                                     'offset' : 57,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UserSvidModeExited)

        UserSvidAttentionVDMReceived = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'User SVID Attention VDM Received',
                                                                     'offset' : 58,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UserSvidAttentionVDMReceived)

        UserSvidOtherVDMReceived = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'User SVID Other VDM Received',
                                                                     'offset' : 59,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UserSvidOtherVDMReceived)


class cData1_0x09_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Data Register for CMD1',
                                                 'address' : 0x09,
                                                 'byte length' : 4,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Data Register for CMD1',
                                                        'offset' : 0,
                                                        'bit length' : 32 })


        word1 = register_class.cHexDMTerminator(self,
                                                                    {'name' : 'Word 1 (Least Significant)',
                                                                     'offset' : 0,
                                                                     'bit length' : 32 })

        self.dataModel.addChild(word1)

#        word2 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 2',
#                                                                     'offset' : 32,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word2)

#        word3 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 3',
#                                                                     'offset' : 64,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word3)

#        word4 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 4',
#                                                                     'offset' : 96,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word4)

#        word5 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 5',
#                                                                     'offset' : 128,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word5)

#        word6 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 6',
#                                                                     'offset' : 160,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word6)

#        word7 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 7',
#                                                                     'offset' : 192,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word7)

#        word8 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 8',
#                                                                     'offset' : 224,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word8)

#        word9 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 9',
#                                                                     'offset' : 256,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word9)

#        word10 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 10',
#                                                                     'offset' : 288,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word10)

#        word11 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 11',
#                                                                     'offset' : 320,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word11)

#        word12 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 12',
#                                                                     'offset' : 352,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word12)

#        word13 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 13',
#                                                                     'offset' : 384,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word13)

#        word14 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 14',
#                                                                     'offset' : 416,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word14)

#        word15 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 15',
#                                                                     'offset' : 448,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word15)

#        word16 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 16',
#                                                                     'offset' : 480,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word16)


class cData2_0x11_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Data Register for CMD2',
                                                 'address' : 0x11,
                                                 'byte length' : 4,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Data Register for CMD1',
                                                        'offset' : 0,
                                                        'bit length' : 32 })


        word1 = register_class.cHexDMTerminator(self,
                                                                    {'name' : 'Word 1 (Least Significant)',
                                                                     'offset' : 0,
                                                                     'bit length' : 32 })

        self.dataModel.addChild(word1)

#        word2 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 2',
#                                                                     'offset' : 32,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word2)

#        word3 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 3',
#                                                                     'offset' : 64,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word3)

#        word4 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 4',
#                                                                     'offset' : 96,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word4)

#        word5 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 5',
#                                                                     'offset' : 128,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word5)

#        word6 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 6',
#                                                                     'offset' : 160,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word6)

#        word7 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 7',
#                                                                     'offset' : 192,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word7)

#        word8 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 8',
#                                                                     'offset' : 224,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word8)

#        word9 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 9',
#                                                                     'offset' : 256,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word9)

#        word10 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 10',
#                                                                     'offset' : 288,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word10)

#        word11 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 11',
#                                                                     'offset' : 320,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word11)

#        word12 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 12',
#                                                                     'offset' : 352,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word12)

#        word13 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 13',
#                                                                     'offset' : 384,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word13)

#        word14 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 14',
#                                                                     'offset' : 416,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word14)

#        word15 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 15',
#                                                                     'offset' : 448,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word15)

#        word16 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 16',
#                                                                     'offset' : 480,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word16)


class cData3_0x1F_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Data Register for CMD3',
                                                 'address' : 0x1F,
                                                 'byte length' : 4,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Data Register for CMD1',
                                                        'offset' : 0,
                                                        'bit length' : 32 })


        word1 = register_class.cHexDMTerminator(self,
                                                                    {'name' : 'Word 1 (Least Significant)',
                                                                     'offset' : 0,
                                                                     'bit length' : 32 })

        self.dataModel.addChild(word1)

#        word2 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 2',
#                                                                     'offset' : 32,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word2)

#        word3 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 3',
#                                                                     'offset' : 64,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word3)

#        word4 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 4',
#                                                                     'offset' : 96,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word4)

#        word5 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 5',
#                                                                     'offset' : 128,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word5)

#        word6 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 6',
#                                                                     'offset' : 160,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word6)

#        word7 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 7',
#                                                                     'offset' : 192,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word7)

#        word8 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 8',
#                                                                     'offset' : 224,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word8)

#        word9 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 9',
#                                                                     'offset' : 256,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word9)

#        word10 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 10',
#                                                                     'offset' : 288,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word10)

#        word11 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 11',
#                                                                     'offset' : 320,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word11)

#        word12 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 12',
#                                                                     'offset' : 352,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word12)

#        word13 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 13',
#                                                                     'offset' : 384,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word13)

#        word14 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 14',
#                                                                     'offset' : 416,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word14)

#        word15 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 15',
#                                                                     'offset' : 448,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word15)

#        word16 = register_class.cHexDMTerminator(self,
#                                                                    {'name' : 'Word 16',
#                                                                     'offset' : 480,
#                                                                     'bit length' : 32 })

#        self.dataModel.addChild(word16)





class cIntMask2_0x17_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Interrupt Mask for I2C2',
                                                 'address' : 0x17,
                                                 'byte length' : 8,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Interrupt Mask for I2C2',
                                                        'offset' : 0,
                                                        'bit length' : 64 })


        SoftReset = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Soft Reset',
                                                                     'offset' : 0,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(SoftReset)

        HardReset = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Hard Reset',
                                                                     'offset' : 1,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(HardReset)

        PowerPathEvent = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Power Path Event',
                                                                     'offset' : 2,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PowerPathEvent)

        PlugInsertOrRemoval = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Plug Insert or Removal',
                                                                     'offset' : 3,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PlugInsertOrRemoval)

        PRSwapComplete = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'PR Swap Complete',
                                                                     'offset' : 4,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PRSwapComplete)

        DRSwapComplete = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'DR Swap Complete',
                                                                     'offset' : 5,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(DRSwapComplete)

        AwokenByHost = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Awoken by Host',
                                                                     'offset' : 6,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(AwokenByHost)

        RdoReceivedFromSink = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'RDO Received from Sink',
                                                                     'offset' : 7,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(RdoReceivedFromSink)

        Bist = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Built-In Self Test',
                                                                     'offset' : 8,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Bist)

        Overcurrent = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Overcurrent Event',
                                                                     'offset' : 9,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Overcurrent)

        AttentionReceived = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Attention Received',
                                                                     'offset' : 10,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(AttentionReceived)

        VDMReceived = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Vendor-Defined Message Received',
                                                                     'offset' : 11,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(VDMReceived)

        NewContractAsCons = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'New Contract as Consumer',
                                                                     'offset' : 12,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(NewContractAsCons)

        NewContractAsProv = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'New Contract as Provider',
                                                                     'offset' : 13,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(NewContractAsProv)

        SourceCapMsgReady = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Source Capabilities Message Ready',
                                                                     'offset' : 14,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(SourceCapMsgReady)

        SinkCapMsgReady = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Sink Capabilities Message Ready',
                                                                     'offset' : 15,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(SinkCapMsgReady)

        SwapRequested = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Swap Requested',
                                                                     'offset' : 17,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(SwapRequested)

        BISTMessageIgnored = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'BIST Message Ignored',
                                                                     'offset' : 18,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(BISTMessageIgnored)

        GotoMinReceived = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'GotoMin Received',
                                                                     'offset' : 19,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(GotoMinReceived)

        UsbHostPresent = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'USB Host Present',
                                                                     'offset' : 20,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UsbHostPresent)

        UsbHostPresentNoLonger = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'USB Host Present No Longer',
                                                                     'offset' : 21,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UsbHostPresentNoLonger)

        HighVoltageWarning = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'High Voltage Warning',
                                                                     'offset' : 22,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(HighVoltageWarning)

        PPswitchChanged = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Power Path Switch Changed',
                                                                     'offset' : 23,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PPswitchChanged)

        PowerStatusUpdate = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Power Status Update',
                                                                     'offset' : 24,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PowerStatusUpdate)

        DataStatusUpdate = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Data Status Update',
                                                                     'offset' : 25,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(DataStatusUpdate)

        StatusUpdate = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Status Update',
                                                                     'offset' : 26,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(StatusUpdate)

        PDStatusUpdate = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'PD Status Update',
                                                                     'offset' : 27,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PDStatusUpdate)

        ADCLowThreshold = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'ADC Low Threshold',
                                                                     'offset' : 28,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(ADCLowThreshold)

        ADCHighThreshold = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'ADC High Threshold',
                                                                     'offset' : 29,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(ADCHighThreshold)

        Cmd1Complete = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'CMD1 Complete',
                                                                     'offset' : 30,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Cmd1Complete)

        Cmd2Complete = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'CMD2 Complete',
                                                                     'offset' : 31,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Cmd2Complete)

        Error_DeviceIncompatible = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Device Incompatible',
                                                                     'offset' : 32,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_DeviceIncompatible)

        Error_CannotProvideVoltageOrCurrent = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Cannot Provide Voltage or Current',
                                                                     'offset' : 33,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_CannotProvideVoltageOrCurrent)

        Error_CanProvideVoltageOrCurrentLater = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Cannot Provide Voltage or Current Later',
                                                                     'offset' : 34,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_CanProvideVoltageOrCurrentLater)

        Error_PowerEventOccurred = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Power Event Occurred',
                                                                     'offset' : 35,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_PowerEventOccurred)

        Error_MissingGetCapMessage = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Missing Get Capabilities Message',
                                                                     'offset' : 36,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_MissingGetCapMessage)

        Error_ProtocolError = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Protocol Error',
                                                                     'offset' : 38,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_ProtocolError)

        Error_MessageData = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Message Data',
                                                                     'offset' : 39,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_MessageData)

        Error_DischargeFailed = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Discharge Failed',
                                                                     'offset' : 41,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_DischargeFailed)

        SnkTransitionComplete = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Sink Transition Complete',
                                                                     'offset' : 42,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(SnkTransitionComplete)

        Error_UnableToSource = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Error: Unable to Source',
                                                                     'offset' : 46,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Error_UnableToSource)

        UserSvidModeEntered = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'User SVID Mode Entered',
                                                                     'offset' : 56,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UserSvidModeEntered)

        UserSvidModeExited = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'User SVID Mode Exited',
                                                                     'offset' : 57,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UserSvidModeExited)

        UserSvidAttentionVDMReceived = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'User SVID Attention VDM Received',
                                                                     'offset' : 58,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UserSvidAttentionVDMReceived)

        UserSvidOtherVDMReceived = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'User SVID Other VDM Received',
                                                                     'offset' : 59,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(UserSvidOtherVDMReceived)

class cStatus_0x1A_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Status',
                                                 'address' : 0x1A,
                                                 'byte length' : 6,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Status',
                                                        'offset' : 0,
                                                        'bit length' : 48 })

        plugPresent = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Plug Present',
                                                                     'offset' : 0,
                                                                     'bit length' : 1 })

        plugPresent.setReportList(['No plug present', 'Plug present, see Conn State (below) for details.'])
        plugPresent.help = """Indicates presence of plug"""
        self.dataModel.addChild(plugPresent)

        connState = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Conn State',
                                                                     'offset' : 1,
                                                                     'bit length' : 3 })

        connState.setReportList(['No connection', 'Port is disabled', 'Audio connection (Ra/Ra)', 'Debug connection (Rd/Rd)', \
                                 'No connection, Ra detected (Ra but no Rd)', 'Reserved (may be used for Rp/Rp Debug connection)', \
                                 'Connection present, no Ra detected (Rd but no Ra) or Rp detected with no previous Ra detection, includes PD Controller that connected in Attached.SNK.', \
                                 'Connection present, Ra detected (Rd and Ra detected) or Rp detected with previous Ra detection (assumes PD Controller started as Source and later swapped to Sink).'])
        connState.help = """Indicates state of connection"""
        self.dataModel.addChild(connState)

        plugOrientation = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Plug Orientation',
                                                                     'offset' : 4,
                                                                     'bit length' : 1 })

        plugOrientation.setReportList(['Upside-up orientation (plug CC on C_CC1) or orientation unknown or port is disabled/disconnected.', \
                                       'Upside-down orientation (plug CC on C_CC2).'])
        plugOrientation.help = """Indicates port orientation when known (requires connection)."""
        self.dataModel.addChild(plugOrientation)

        portRole = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Port Role',
                                                                     'offset' : 5,
                                                                     'bit length' : 1 })
        portRole.setReportList(['PD Controller is Sink (C_CCx pull-down active) or port is disabled/disconnected.', \
                                'PD Controller is Source (C_CCx pull-up active).'])
        portRole.help = """Indicates current state of PD Controller C_CCx pulls, and therefore PD Controller Power Role, once connected. This bit does not toggle during Unattached.* state transitions."""
        self.dataModel.addChild(portRole)


        dataRole = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Data Role',
                                                                     'offset' : 6,
                                                                     'bit length' : 1 })
        dataRole.setReportList(['PD Controller is UFP or port is disabled/disconnected.', 'PD Controller is DFP.'])
        dataRole.help = """Indicates current state of PD Controller Data Role once connected."""
        self.dataModel.addChild(dataRole)

        vconnEn = register_class.cListDMTerminator(self,
                                                                    {'name' : 'VConn Enabled',
                                                                     'offset' : 7,
                                                                     'bit length' : 1 })
        vconnEn.setReportList(['VConn not supplied by this controller', 'VConn is supplied by this controller'])
        vconnEn.help = """Indicates whether this PD controller is supplying VConn power to the cable"""
        self.dataModel.addChild(vconnEn)

        ppSwitchList = ['Disabled', 'Disabled due to Overcurrent', 'Enabled Reverse current from VBUS to Power Path blocked (acting as output)', 'Enabled Reverse current from Power Path to VBUS blocked (acting as input)']


        pp5v = register_class.cListDMTerminator(self,
                                                                    {'name' : 'PP_5V Switch',
                                                                     'offset' : 8,
                                                                     'bit length' : 2 })
        pp5v.setReportList(ppSwitchList)
        pp5v.help = """Indicates whether this power path switch is enabled and whether reverse current protection is enabled and in which direction."""
        self.dataModel.addChild(pp5v)

        ppHv = register_class.cListDMTerminator(self,
                                                                    {'name' : 'PP_HV Switch',
                                                                     'offset' : 10,
                                                                     'bit length' : 2 })
        ppHv.setReportList(ppSwitchList)
        ppHv.help = """Indicates whether this power path switch is enabled and whether reverse current protection is enabled and in which direction."""
        self.dataModel.addChild(ppHv)

        ppHve = register_class.cListDMTerminator(self,
                                                                    {'name' : 'PP_HVE Switch',
                                                                     'offset' : 12,
                                                                     'bit length' : 2 })
        ppHve.setReportList(ppSwitchList)
        ppHve.help = """Indicates whether this power path switch is enabled and whether reverse current protection is enabled and in which direction."""
        self.dataModel.addChild(ppHve)

        ppCablelist = ['Disabled', 'Disabled due to Overcurrent', 'PP_CABLE enabled on C_CC1', 'PP_CABLE enabled on C_CC2' ]

        ppCable = register_class.cListDMTerminator(self,
                                                                    {'name' : 'PP_Cable Switch',
                                                                     'offset' : 14,
                                                                     'bit length' : 2 })
        ppCable.setReportList(ppCablelist)
        ppCable.help = """Indicates whether the PP_Cable (VConn) power path switch is enabled and on which configuration channel (cc)."""
        self.dataModel.addChild(ppCable)

        overCurr = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Overcurrent',
                                                                     'offset' : 16,
                                                                     'bit length' : 1 })
        overCurr.setReportList(['VConn not supplied by this controller', 'VConn is supplied by this controller'])
        overCurr.help = """Indicates whether an overcurrent event has been detected"""
        self.dataModel.addChild(overCurr)


        powSourceList = ['Unknown', 'VIN_3V3', 'PP_Cable', 'VBus' ]

        powSource = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Power Source',
                                                                     'offset' : 18,
                                                                     'bit length' : 2 })
        powSource.setReportList(powSourceList)
        powSource.help = """Indicates whether the PD controller is being supplied from VIN_3V3, PP_Cable or VBus."""
        self.dataModel.addChild(powSource)


        vbusStatus = register_class.cListDMTerminator(self,
                                                    {'name' : 'VBUS Status',
                                                     'offset' : 20,
                                                     'bit length' : 2 })
        vbusStatus.setReportList(['VBUS is at vSafe0V (less than 0.8V)', \
                                  'VBUS is at vSafe5V (4.75V to 5.5V). See ADC Results for exact voltage provided multichannel ADC is active.',  \
                                  'VBUS is at other PD-negotiated power level and within expected limits. See ADC Results for exact voltage provided multi-channel ADC is active.', \
                                  'VBUS is not within any of the above ranges. See ADC Results for exact voltage provided multi-channel ADC is active.' ])
        vbusStatus.help = """Indicates status of VBUS."""
        self.dataModel.addChild(vbusStatus)

        usbHostPresent = register_class.cListDMTerminator(self,
                                                    {'name' : 'USB Host Present',
                                                     'offset' : 22,
                                                     'bit length' : 2 })
        usbHostPresent.setReportList(['No far-end device present providing VBUS or PD Controller power role is Source.', \
                                  'VBUS is being provided by a far-end device that is a PD device not capable of USB communications', \
                                  'VBUS is being provided by a far-end device that is not a PD device.', \
                                  'VBUS is being provided by a far-end device that is a PD device capable of USB communications.'])
        usbHostPresent.help = """Indicates presence of USB Host"""
        self.dataModel.addChild(usbHostPresent)

        actingAsLegacy = register_class.cListDMTerminator(self,
                                                    {'name' : 'Acting as Legacy',
                                                     'offset' : 24,
                                                     'bit length' : 2 })
        actingAsLegacy.setReportList(['PD Controller is not in a legacy (non PD mode).', \
                                      'PD Controller is acting like a legacy sink. It will not respond to USB PD message traffic.', \
                                      'PD Controller is acting like a legacy source. It will not respond to USB PD message traffic.'])
        actingAsLegacy.setMaxValue(3)
        actingAsLegacy.help = """Indicates when PD Controller has gone into a mode where it is acting like a legacy (non PD) device."""
        self.dataModel.addChild(actingAsLegacy)

        goToMinActive = register_class.cListDMTerminator(self,
                                                    {'name' : 'Go To Min Active',
                                                     'offset' : 26,
                                                     'bit length' : 1 })
        goToMinActive.setReportList(['No PD contract established or GotoMin restriction has been cleared by Source Capabilities message or disconnect/Hard Reset.', \
                                     'GotoMin has been received as Sink or sent as Source'])
        goToMinActive.help = """Indicates whether GoToMin has been received"""
        self.dataModel.addChild(goToMinActive)

        bist = register_class.cListDMTerminator(self,
                                                    {'name' : 'BIST',
                                                     'offset' : 27,
                                                     'bit length' : 1 })
        bist.setReportList(['No BIST in progress','BIST in progress'])
        bist.help = """Indicates status of BIST"""
        self.dataModel.addChild(bist)

        HVWarn = register_class.cListDMTerminator(self,
                                                    {'name' : 'High Voltage Warning',
                                                     'offset' : 28,
                                                     'bit length' : 1 })
        HVWarn.setReportList(['PD Controller operating as Sink or VBUS voltage is below limit specified by HighVoltageWarningLimit register or port is disconnected.', \
                              'PD Controller operating as Source and VBUS voltage is above limit specified by HighVoltageWarningLimit register.'])
        HVWarn.help = """Indicates if HighVoltageWarning Limit is triggered"""
        self.dataModel.addChild(HVWarn)

        LVWarn = register_class.cListDMTerminator(self,
                                                    {'name' : 'Low Voltage Warning',
                                                     'offset' : 29,
                                                     'bit length' : 1 })
        LVWarn.setReportList(['PD Controller operating as Sink or VBUS voltage is above limit specified by LowVoltageWarningLimit register or port is disconnected.', \
                              'PD Controller operating as Source and VBUS voltage is below limit specified by LowVoltageWarningLimit register.'])
        LVWarn.help = """Indicates if LowVoltageWarning Limit is triggered"""
        self.dataModel.addChild(LVWarn)

        AMStatus = register_class.cListDMTerminator(self,
                                                    {'name' : 'Alternative Mode Status',
                                                     'offset' : 32,
                                                     'bit length' : 3 })
        AMStatus.setMaxValue(4)
        AMStatus.setReportList(['No Alternate Modes attempted.', \
                                'At least one Alternate Mode entry successful.', \
                                'At least one Alternate Mode entry unsuccessful.' \
                                'At least one Alternate Mode entry successful and at least one mode entry unsuccessful.'])
        AMStatus.help = """Indicates if AM entry, if any, is successful"""
        self.dataModel.addChild(AMStatus)


class cSystemPowerState_0x20_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'System Power State',
                                                 'address' : 0x20,
                                                 'byte length' : 1,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'System Power State',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        sysPowReportDict = { 0 : 'Do Not Sleep', 3 : 'Sleep, I2C Remains Active', 5 : 'Sleep, I2C Looses First Transaction' }
        sysPowReplaceDict = { 1:0, 2:0, 4:5}

        sysPowState = register_class.cDictDMTerminator(self,
                                        {'name' : 'Sleep Mode (When Allowed)',
                                         'offset' : 0,
                                         'bit length' : 3 })

        sysPowState.setReportDict(sysPowReportDict)
        sysPowState.setReplaceDict(sysPowReplaceDict)

        self.dataModel.addChild(sysPowState)


class cSysConfig_0x28_register(register_class.cRegister) :
    def __init__(self):
        self.FIXED_STRING_INDICES = True

        register_class.cRegister.__init__(self, {'register name' : 'System Configuration',
                                                 'address' : 0x28,
                                                 'byte length' : 18,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'System Configuration',
                                                         'offset' : 0,
                                                         'bit length' : 144 })


        PortInfo = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Port Information',
                                                                     'offset' : 0,
                                                                     'bit length' : 3 })

        PortInfo.setReportList(['Presents R_d on CC, no data/power role swap', 'Audio Accessory', \
                                'Presents R_d on CC, supports data/power role swap', \
                                'Toggles R_p/R_d on CC (no try.Src), supports data/power role swap', \
                                'Presents R_p on CC, supports data/power role swap', \
                                'Toggles R_p/R_d on CC (with try.Src), supports data/power role swap', \
                                'Presents R_p on CC, no data/power role swap', 'Disabled (does not present R_p or R_d)' \
                                ])

        self.dataModel.addChild(PortInfo)

        ReceptType = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Receptacle Type',
                                                                     'offset' : 3,
                                                                     'bit length' : 3 })

        ReceptType.setMaxValue(3)
        ReceptType.setReportList(['Standard USB2-only USB-C receptacle', \
                                  'Standard fully-featured USB-C receptacle', \
                                  'Tethered USB2-only cable with USB-C plug', \
                                  'Tethered fully-featured cable with USB-C plug', \
                                  ])

        self.dataModel.addChild(ReceptType)


        TypeCCurr = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Type-C Current',
                                                                     'offset' : 6,
                                                                     'bit length' : 2 })
        TypeCCurr.setMaxValue(2)
        TypeCCurr.setReportList(['Default Current (weakest pullup)', \
                                 '1.5 A (medium pullup)', \
                                 '3 A (strongest pullup)', \
                                 ])

        self.dataModel.addChild(TypeCCurr)

        TypeCPeak = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Type-C Current OCP Peak Current',
                                                                     'offset' : 10,
                                                                     'bit length' : 2 })

        TypeCPeak.setMaxValue(2)

        TypeCPeak.setReportList(['100%', \
                                 '150%', \
                                 '200%', \
                                 ])

        self.dataModel.addChild(TypeCPeak)

        VConnSupp = register_class.cListDMTerminator(self,
                                                                    {'name' : 'V_CONN Supported',
                                                                     'offset' : 8,
                                                                     'bit length' : 2 })

        VConnSupp.setReportList(['VCONN not supported (disabled)', \
                                 'Reserved', \
                                 'VCONN supported as DFP only (reject VCONN_Swap requests)', \
                                 'VCONN supported as DFP/UFP (accept VCONN_Swap requests)', \
                                 ])
        # Check with Steve on the Reserved field

        self.dataModel.addChild(VConnSupp)


        HVWarn = register_class.cListDMTerminator(self,
                                                                    {'name' : 'High Voltage Warning Level',
                                                                     'offset' : 14,
                                                                     'bit length' : 1 })

        HVWarn.setReportList(['Warning when source VBUS voltage exceeds 10% from nominal', \
                              'Warning when source VBUS voltage exceeds 20% from nominal', \
                              ])
        self.dataModel.addChild(HVWarn)

        LVWarn = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Low Voltage Warning Level',
                                                                     'offset' : 15,
                                                                     'bit length' : 1 })

        LVWarn.setReportList(['Warning when source VBUS Voltage dips below 10% from nominal', \
                              'Warning when source VBUS Voltage dips below 20% from nominal', \
                              ])
        # Check with Steve for correctness of list descriptions
        self.dataModel.addChild(LVWarn)

        OVPtrip = cOVPVoltageField(self,
                                                                    {'name' : 'Over Voltage Protection Trip Point',
                                                                     'offset' : 16,
                                                                     'bit length' : 6 })

        self.dataModel.addChild(OVPtrip)

        OVPUsage = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Over Voltage Protection Usage',
                                                                     'offset' : 22,
                                                                     'bit length' : 2 })

        OVPUsage.setReportList(['Disconnect VBUS if voltage exceeds OVPTripPoint', \
                                'Disconnect VBUS if voltage exceeds 5% of expected max.', \
                                'Disconnect VBUS if voltage exceeds 10% of expected max.', \
                                'Disconnect VBUS if voltage exceeds 15% of expected max.', \
                                ])

        self.dataModel.addChild(OVPUsage)

        PP5VConf = register_class.cListDMTerminator(self,
                                                                    {'name' : 'PP_5V0 Configuration',
                                                                     'offset' : 24,
                                                                     'bit length' : 2 })
        PP5VConf.setMaxValue(1)
        PP5VConf.setReportList(['PP_5V0 switch not used (disabled)', \
                                'PP_5V0 switch configured for output', \
                                ])

        self.dataModel.addChild(PP5VConf)

        PPHVConf = register_class.cListDMTerminator(self,
                                                                    {'name' : 'PP_HV Configuration',
                                                                     'offset' : 26,
                                                                     'bit length' : 2 })

        PPHVConf.setReportList(['PP_HV switch not used (disabled)', \
                                'PP_HV switch configured for output', \
                                'PP_HV switch configured for input', \
                                'PP_HV switch configured for input, wait for SYS_RDY command', \
                                ])

        self.dataModel.addChild(PPHVConf)

        PPExtConf = register_class.cListDMTerminator(self,
                                                                    {'name' : 'PP_EXT Configuration',
                                                                     'offset' : 28,
                                                                     'bit length' : 3 })

        PPExtConf.setMaxValue(5)
        PPExtConf.setReportList(['PP_EXT not used (disabled)', \
                                 'PP_EXT configured for output', \
                                 'PP_EXT configured for input', \
                                 'PP_EXT configured for input, wait for SYS_RDY command', \
                                 'PP_EXT configured for input and output', \
                                 'PP_EXT configured for input and output, wait for SYS_RDY command', \
                                 ])

        self.dataModel.addChild(PPExtConf)

        BC12Enable = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'BC 1.2 Enable',
                                                                     'offset' : 32,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(BC12Enable)

        USBRPEn = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'USB RP Enable',
                                                                     'offset' : 33,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(USBRPEn)

        USBEPEn = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'USB EP Enable',
                                                                     'offset' : 34,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(USBEPEn)

        USB3Rate = register_class.cListDMTerminator(self,
                                                                    {'name' : 'USB3.0/3.1 Rate',
                                                                     'offset' : 35,
                                                                     'bit length' : 2 })
        USB3Rate.setMaxValue(2)
        USB3Rate.setReportList(['USB3 not supported', \
                                'USB3 Gen1 signaling rate supported', \
                                'USB3 Gen2 signaling rate supported', \
                                ])

        self.dataModel.addChild(USB3Rate)

        USB2Supp = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'USB2.0 Supported',
                                                                     'offset' : 37,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(USB2Supp)

        AudAccSupp = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Audio Accessory Support',
                                                                     'offset' : 38,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(AudAccSupp)

        DbgAccSupp = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Debug Accessory Support',
                                                                     'offset' : 39,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(DbgAccSupp)


        PowAccSupp = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Powered Accessory Support',
                                                                     'offset' : 40,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PowAccSupp)

        RSense = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Rsense (External Sense Resistor)',
                                                                     'offset' : 41,
                                                                     'bit length' : 1 })

        RSense.setReportList(['10 mOhm', \
                                '5 mOhm' ])

        self.dataModel.addChild(RSense)

        TrySrc = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Try.Src (Try Source Support)',
                                                                     'offset' : 42,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(TrySrc)

        Billboard = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'USB2.0 Endpoint Billboard Enable',
                                                                     'offset' : 43,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Billboard)


        PPExtOctEnableBool = register_class.cBooleanDMTerminator( self,  { 'name' : 'External Power Path Over-Current Timeout Enable',
                                                                'offset' : 50,
                                                                'bit length' : 1 } )

        PPExtOctEnable = register_class.cForceSetDMTerminator( self,  { 'name' : 'External Power Path Over-Current Timeout Enable',
                                                                'offset' : 50,
                                                                'bit length' : 1,
                                                                'force value' : int(1),
                                                                'force display' : 'Enabled',
                                                                'display widget' : PPExtOctEnableBool })


        self.dataModel.addChild(PPExtOctEnable)
        PPExtOctEnable.setFromInt(1)

        PPExtOct = register_class.cDictDMTerminator(self,
                                                                    {'name' : 'External Power Path Over-current Timeout',
                                                                     'offset' : 46,
                                                                     'bit length' : 4 })

        PPExtOct.setMaxValue(9)
        PPExtOct.setReportDict({0x04 : '640 us', \
                                0x05 : '1.28 ms', \
                                0x06 : '5.12 ms', \
                                0x07 : '10.24 ms', \
                                0x08 : '40.96 ms', \
                                0x09 : '81.92 ms', \
                                })

        PPExtOct.setReplaceDict({0x00 : 0x04, \
                                0x01 : 0x04, \
                                0x02 : 0x04, \
                                0x03 : 0x04, \
                                })


        self.dataModel.addChild(PPExtOct)

        ResetZTOCount = register_class.cDecimalDMTerminator(self,
                                                                    {'name' : 'Reset Z Timeout Count',
                                                                     'offset' : 51,
                                                                     'bit length' : 6 })

        self.dataModel.addChild(ResetZTOCount)

        ResetZTOClock = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Reset Z Timeout Clock',
                                                                     'offset' : 57,
                                                                     'bit length' : 2 })

        ResetZTOClock.setReportList(['160 us', \
                                     '640 us', \
                                     '1.28 ms', \
                                     '5.12 ms', \
                                     ])

        self.dataModel.addChild(ResetZTOClock)

        Vout3v3thresh = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Vout3V3 (3.3 V output) threshold',
                                                                     'offset' : 59,
                                                                     'bit length' : 3 })

        Vout3v3thresh.setReportList(['1.125 V', \
                                     '2.25 V', \
                                     '2.375 V', \
                                     '2.5 V', \
                                     '1.625 V', \
                                     '2.75 V', \
                                     '2.875 V', \
                                     '3.0 V', \
                                     ])

        self.dataModel.addChild(Vout3v3thresh)

        Vout3v3enable = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Vout3V3 (3.3 V output) enable',
                                                                     'offset' : 62,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(Vout3v3enable)

        ccDisconnectSink = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Sense Disconnect on CC (in addition to VBUS) when Sink',
                                                                     'offset' : 64,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(ccDisconnectSink)


        setUvpTo4P5 = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Set Under-voltage Protection to 4.5V always',
                                                                     'offset' : 66,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(setUvpTo4P5)

        UvpTripPoint5V = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Under-voltage Protection Trip Point, PP_5V',
                                                                     'offset' : 67,
                                                                     'bit length' : 3 })

        UvpTripPoint5V.setReportList(['5%', \
                                     '10%', \
                                     '15%', \
                                     '20%', \
                                     '25%', \
                                     '30%', \
                                     '40%', \
                                     '50%', \
                                     ])

        self.dataModel.addChild(UvpTripPoint5V)

        UvpUsageHV = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Under-voltage Protection Usage, PP_HV',
                                                                     'offset' : 70,
                                                                     'bit length' : 3 })

        UvpUsageHV.setReportList(['5%', \
                                    '10%', \
                                     '15%', \
                                     '20%', \
                                     '25%', \
                                     '30%', \
                                     '40%', \
                                     '50%', \
                                     ])

        self.dataModel.addChild(UvpUsageHV)

        UDisList = ['UART Enabled (0)', 'UART Disabled (1)']

        UARTDis = register_class.cListDMTerminator(self,
                                                                    {'name' : 'UART Disable',
                                                                     'offset' : 79,
                                                                     'bit length' : 1 })

        UARTDis.setReportList(UDisList)
        self.dataModel.addChild(UARTDis)

        serStrIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Serial String Index',
                                                                     'offset' : 80,
                                                                     'bit length' : 1 })

        serStrIndex.setReportList(['No Serial Number String', 'Serial Number String at Index 1' ])

        if (self.FIXED_STRING_INDICES == True) :
            serStrIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Serial String Index',
                                                                    'offset' : 80,
                                                                    'bit length' : 1,
                                                                    'force value' : int(1),
                                                                    'force display' : 'Serial Number String at Index 1',
                                                                    'display widget' : serStrIndex })
            self.dataModel.addChild(serStrIndexFixed)
            serStrIndexFixed.setFromInt(1)
        else:
            self.dataModel.addChild(serStrIndex)



        prodStrIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Product String Index',
                                                                     'offset' : 81,
                                                                     'bit length' : 2 })

        prodStrIndex.setReportList(['No Product String', 'Product String at Index 1', \
                                   'Product String at Index 2', 'Product String at Index 3' ])


        if (self.FIXED_STRING_INDICES == True) :
            prodStrIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Product String Index',
                                                                    'offset' : 81,
                                                                    'bit length' : 2,
                                                                    'force value' : int(2),
                                                                    'force display' : 'Product String at Index 2',
                                                                    'display widget' : prodStrIndex })
            self.dataModel.addChild(prodStrIndexFixed)
            prodStrIndexFixed.setFromInt(2)
        else:
            self.dataModel.addChild(prodStrIndex)


        manufactStrIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Manufacturer String Index',
                                                                     'offset' : 83,
                                                                     'bit length' : 2 })

        manufactStrIndex.setReportList(['No Manufacturer String', 'Manufacturer String at Index 1', \
                                   'Manufacturer String at Index 2', 'Manufacturer String at Index 3' ])


        if (self.FIXED_STRING_INDICES == True) :
            manufactStrIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Manufacturer String Index',
                                                                    'offset' : 83,
                                                                    'bit length' : 2,
                                                                    'force value' : int(3),
                                                                    'force display' : 'Manufacturer String at Index 3',
                                                                    'display widget' : manufactStrIndex })
            self.dataModel.addChild(manufactStrIndexFixed)
            manufactStrIndexFixed.setFromInt(3)
        else :
            self.dataModel.addChild(manufactStrIndex)

        billboardURLStrIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Billboard URL String Index',
                                                                     'offset' : 85,
                                                                     'bit length' : 3 })

        billboardURLStrIndex.setReportList(['No Billboard URL String', 'Billboard URL String at Index 1', \
                                   'Billboard URL String at Index 2', 'Billboard URL String at Index 3', \
                                   'Billboard URL String at Index 4', 'Billboard URL String at Index 5', \
                                   'Billboard URL String at Index 6', 'Billboard URL String at Index 7' ])

        if (self.FIXED_STRING_INDICES == True) :
            billboardURLStrIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Billboard URL String Index',
                                                                    'offset' : 85,
                                                                    'bit length' : 3,
                                                                    'force value' : int(4),
                                                                    'force display' : 'Billboard URL String at Index 4',
                                                                    'display widget' : billboardURLStrIndex })
            self.dataModel.addChild(billboardURLStrIndexFixed)
            billboardURLStrIndexFixed.setFromInt(4)
        else :
            self.dataModel.addChild(billboardURLStrIndex)


        intTBTStrIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Intel Thuderbolt Billboard String Index',
                                                                     'offset' : 88,
                                                                     'bit length' : 4 })

        string_list = ['No TBT Billboard String',]
        for i in range(1,16) :
            string_list.append('TBT Billboard String at Index %d' %i)

        intTBTStrIndex.setReportList(string_list)

        if (self.FIXED_STRING_INDICES == True) :
            intTBTStrIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Intel Thuderbolt Billboard String Index',
                                                                    'offset' : 88,
                                                                    'bit length' : 4,
                                                                    'force value' : int(5),
                                                                    'force display' : 'TBT Billboard String at Index 5',
                                                                    'display widget' : billboardURLStrIndex })
            self.dataModel.addChild(intTBTStrIndexFixed)
            intTBTStrIndexFixed.setFromInt(5)
        else :
            self.dataModel.addChild(intTBTStrIndex)

        string_list = ['No DisplayPort Billboard String',]
        for i in range(1,16) :
            string_list.append('DisplayPort Billboard String at Index %d' %i)

        displayPortStrIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'DisplayPort Billboard String Index',
                                                                     'offset' : 96,
                                                                     'bit length' : 4 })

        displayPortStrIndex.setReportList(string_list)

        if (self.FIXED_STRING_INDICES == True) :
            displayPortStrIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'DisplayPort Billboard String Index',
                                                                    'offset' : 96,
                                                                    'bit length' : 4,
                                                                    'force value' : int(6),
                                                                    'force display' : 'DisplayPort Billboard String at Index 6',
                                                                    'display widget' : displayPortStrIndex })
            self.dataModel.addChild(displayPortStrIndexFixed)
            displayPortStrIndexFixed.setFromInt(6)
        else :
            self.dataModel.addChild(displayPortStrIndex)


        string_list = ['No Custom Vendor ID 1 Billboard String',]
        for i in range(1,16) :
            string_list.append('Custom Vendor ID 1 Billboard String at Index %d' %i)

        cust1VidStrIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Custom Vendor ID 1 String Index',
                                                                     'offset' : 104,
                                                                     'bit length' : 4 })

        cust1VidStrIndex.setReportList(string_list)

        if (self.FIXED_STRING_INDICES == True) :
            cust1VidStrIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Custom Vendor ID 1 String Index',
                                                                    'offset' : 104,
                                                                    'bit length' : 4,
                                                                    'force value' : int(0),
                                                                    'force display' : 'No Custom Vendor ID 1 Billboard String',
                                                                    'display widget' : cust1VidStrIndex })
            self.dataModel.addChild(cust1VidStrIndexFixed)
            cust1VidStrIndexFixed.setFromInt(0)
        else :
            self.dataModel.addChild(cust1VidStrIndex)


        string_list = ['No Custom Vendor ID 2 Billboard String',]
        for i in range(1,16) :
            string_list.append('Custom Vendor ID 2 Billboard String at Index %d' %i)

        cust2VidStrIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Custom Vendor ID 2 Billboard String Index',
                                                                     'offset' : 108,
                                                                     'bit length' : 4 })

        cust2VidStrIndex.setReportList(string_list)

        if (self.FIXED_STRING_INDICES == True) :
            cust2VidStrIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Custom Vendor ID 2 String Index',
                                                                    'offset' : 108,
                                                                    'bit length' : 4,
                                                                    'force value' : int(0),
                                                                    'force display' : 'No Custom Vendor ID 2 Billboard String',
                                                                    'display widget' : cust2VidStrIndex })
            self.dataModel.addChild(cust2VidStrIndexFixed)
            cust2VidStrIndexFixed.setFromInt(0)
        else :
            self.dataModel.addChild(cust2VidStrIndex)

        string_list = ['No Custom Vendor ID 3 Billboard String',]
        for i in range(1,16) :
            string_list.append('Custom Vendor ID 3 Billboard String at Index %d' %i)

        cust3VidStrIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Custom Vendor ID 3 Billboard String Index',
                                                                     'offset' : 112,
                                                                     'bit length' : 4 })

        cust3VidStrIndex.setReportList(string_list)

        if (self.FIXED_STRING_INDICES == True) :
            cust3VidStrIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Custom Vendor ID 3 String Index',
                                                                    'offset' : 112,
                                                                    'bit length' : 4,
                                                                    'force value' : int(0),
                                                                    'force display' : 'No Custom Vendor ID 3 Billboard String',
                                                                    'display widget' : cust3VidStrIndex })
            self.dataModel.addChild(cust3VidStrIndexFixed)
            cust3VidStrIndexFixed.setFromInt(0)
        else :
            self.dataModel.addChild(cust3VidStrIndex)

        string_list = ['No Custom Vendor ID 4 Billboard String',]
        for i in range(1,16) :
            string_list.append('Custom Vendor ID 4 Billboard String at Index %d' %i)

        cust4VidStrIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Custom Vendor ID 4 Billboard String Index',
                                                                     'offset' : 116,
                                                                     'bit length' : 4 })

        cust4VidStrIndex.setReportList(string_list)

        if (self.FIXED_STRING_INDICES == True) :
            cust4VidStrIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Custom Vendor ID 4 String Index',
                                                                    'offset' : 116,
                                                                    'bit length' : 4,
                                                                    'force value' : int(0),
                                                                    'force display' : 'No Custom Vendor ID 4 Billboard String',
                                                                    'display widget' : cust4VidStrIndex })
            self.dataModel.addChild(cust4VidStrIndexFixed)
            cust4VidStrIndexFixed.setFromInt(0)
        else :
            self.dataModel.addChild(cust4VidStrIndex)

        PP5vOctEnableBool = register_class.cBooleanDMTerminator( self,  { 'name' : 'Internal 5V Power Path Over-Current Timeout Enable',
                                                                'offset' : 124,
                                                                'bit length' : 1 } )

        PP5vOctEnable = register_class.cForceSetDMTerminator( self,  { 'name' : 'Internal 5V Power Path Over-Current Timeout Enable',
                                                                'offset' : 124,
                                                                'bit length' : 1,
                                                                'force value' : int(1),
                                                                'force display' : 'Enabled',
                                                                'display widget' : PP5vOctEnableBool })

        self.dataModel.addChild(PP5vOctEnable)
        PP5vOctEnable.setFromInt(1)



        PP5vOct = register_class.cDictDMTerminator(self,
                                                                    {'name' : 'Internal 5V Power Path Over-current Timeout',
                                                                     'offset' : 120,
                                                                     'bit length' : 4 })

        PP5vOct.setMaxValue(9)
        PP5vOct.setReportDict({0x04 : '640 us', \
                                0x05 : '1.28 ms', \
                                0x06 : '5.12 ms', \
                                0x07 : '10.24 ms', \
                                0x08 : '40.96 ms', \
                                0x09 : '81.92 ms', \
                                })

        PP5vOct.setReplaceDict({0x00 : 0x04, \
                                0x01 : 0x04, \
                                0x02 : 0x04, \
                                0x03 : 0x04, \
                                })


        self.dataModel.addChild(PP5vOct)


        PPHvOctEnableBool = register_class.cBooleanDMTerminator( self,  { 'name' : 'Internal HV Power Path Over-Current Timeout Enable',
                                                                'offset' : 132,
                                                                'bit length' : 1 } )

        PPHvOctEnable = register_class.cForceSetDMTerminator( self,  { 'name' : 'Internal HV Power Path Over-Current Timeout Enable',
                                                                'offset' : 132,
                                                                'bit length' : 1,
                                                                'force value' : int(1),
                                                                'force display' : 'Enabled',
                                                                'display widget' : PPHvOctEnableBool })

        self.dataModel.addChild(PPHvOctEnable)
        PPHvOctEnable.setFromInt(1)


        PPHvOct = register_class.cDictDMTerminator(self,
                                                                    {'name' : 'Internal HV Power Path Over-current Timeout',
                                                                     'offset' : 128,
                                                                     'bit length' : 4 })

        PPHvOct.setMaxValue(9)
        PPHvOct.setReportDict({0x04 : '640 us', \
                                0x05 : '1.28 ms', \
                                0x06 : '5.12 ms', \
                                0x07 : '10.24 ms', \
                                0x08 : '40.96 ms', \
                                0x09 : '81.92 ms', \
                                })

        PPHvOct.setReplaceDict({0x00 : 0x04, \
                                0x01 : 0x04, \
                                0x02 : 0x04, \
                                0x03 : 0x04, \
                                })


        self.dataModel.addChild(PPHvOct)

        gpioThresh = cAdjustableThresholdGPIO(self,
                                                                    {'name' : 'Voltage Threshold for Adjustable GPIO Event',
                                                                     'offset' : 136,
                                                                     'bit length' : 8 })
        self.dataModel.addChild(gpioThresh)


class cControlConfig_0x29_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Control Configuration',
                                                 'address' : 0x29,
                                                 'byte length' : 5,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Control Configuration',
                                                         'offset' : 0,
                                                         'bit length' : 40 })



        disablePD = register_class.cListDMTerminator(self,
                                                                    {'name' : 'PD Mode',
                                                                     'offset' : 0,
                                                                     'bit length' : 2 })

        disablePD.setMaxValue(2)

        disablePD.setReportList(['Normal PD Behavior', \
                                 'Legacy USB Host/Source', \
                                 'Legacy USB Device/Sink'
                                 ])

        self.dataModel.addChild(disablePD)

        externallyPowered = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Externally Powered',
                                                                     'offset' : 2,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(externallyPowered)

        neverSinkEP = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Never Sink if Externally Powered',
                                                                     'offset' : 30,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(neverSinkEP)


        processSwTSk = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Process Swap To Sink',
                                                                     'offset' : 4,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(processSwTSk)

        initSwTSk = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Initiate Swap To Sink',
                                                                     'offset' : 5,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(initSwTSk)

        processSwTSr = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Process Swap To Source',
                                                                     'offset' : 6,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(processSwTSr)

        initSwTSr = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Initiate Swap To Source',
                                                                     'offset' : 7,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(initSwTSr)

        rdoInt = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'RDO Intrusive Mode',
                                                                     'offset' : 8,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(rdoInt)

        pdoInt = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'PDO Intrusive Mode',
                                                                     'offset' : 9,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(pdoInt)

        procVconnSw = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Process VCONN Swap',
                                                                     'offset' : 10,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(procVconnSw)

        initVconnSw = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Initiate VCONN Swap',
                                                                     'offset' : 11,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(initVconnSw)

        procSwUFP = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Process Swap to UFP',
                                                                     'offset' : 12,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(procSwUFP)

        initSwUFP = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Initiate Swap to UFP',
                                                                     'offset' : 13,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(initSwUFP)

        procSwDFP = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Process Swap to DFP',
                                                                     'offset' : 14,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(procSwDFP)

        initSwDFP = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Initiate Swap to DFP',
                                                                     'offset' : 15,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(initSwDFP)

        autoSinkCap = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Automatic Sink Capabilities Request',
                                                                     'offset' : 16,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(autoSinkCap)



        autoID = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Automatic ID Request',
                                                                     'offset' : 24,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(autoID)

        amIntrusive = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Intrusive Alternate Mode Support',
                                                                     'offset' : 25,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(amIntrusive)

        forceUSBGen1 = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Force USB Generation 1',
                                                                     'offset' : 31,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(forceUSBGen1)

        i2cTimeout = cI2CTimeoutField(self,
                                                                    {'name' : 'I2C Timeout Period',
                                                                     'offset' : 32,
                                                                     'bit length' : 3 })

        self.dataModel.addChild(i2cTimeout)


class cBootFlags_0x2D_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Boot Flags',
                                                 'address' : 0x2D,
                                                 'byte length' : 12,
                                                 'permission' : 'DRO'})


        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Boot Flags',
                                                         'offset' : 0,
                                                         'bit length' : 96 })

        PatchHeaderErr = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Boot Successful',
                                                                     'offset' : 0,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(PatchHeaderErr)

        ppext = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'PP_EXT Switch Closed',
                                                                     'offset' : 1,
                                                                     'bit length' : 1 })

        ppext.help = """PP_EXT closed due to dead battery boot."""
        self.dataModel.addChild(ppext)

        DeadBatteryFlag = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Dead Battery Flag',
                                                                     'offset' : 2,
                                                                     'bit length' : 1 })

        DeadBatteryFlag.help = """The Device has booted in Dead Battery Mode"""
        self.dataModel.addChild(DeadBatteryFlag)

        SpiFlashPresent = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'SPI Flash Present',
                                                                     'offset' : 3,
                                                                     'bit length' : 1 })

        SpiFlashPresent.help = """SPI_MISO pin was not grounded at boot, response received from SPI flash device. PD Controller is the primary device"""
        self.dataModel.addChild(SpiFlashPresent)

        Region0 = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Region 0',
                                                                     'offset' : 4,
                                                                     'bit length' : 1 })

        Region0.help = """Region 0 of the SPI Memory was attempted."""
        self.dataModel.addChild(Region0)

        Region1 = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Region 1',
                                                                     'offset' : 5,
                                                                     'bit length' : 1 })

        Region1.help = """Region 1 of the SPI Memory was attempted."""
        self.dataModel.addChild(Region1)

        Region0Invalid = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Region 0 Invalid',
                                                                     'offset' : 6,
                                                                     'bit length' : 1 })

        Region0Invalid.help = """Region 0 of the SPI Memory was invalid"""
        self.dataModel.addChild(Region0Invalid)

        Region1Invalid = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Region 1 Invalid',
                                                                     'offset' : 7,
                                                                     'bit length' : 1 })

        Region1Invalid.help = """Region 1 of the SPI Memory was invalid"""
        self.dataModel.addChild(Region1Invalid)

        Region0FlashErr = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Region 0 Flash Error',
                                                                     'offset' : 8,
                                                                     'bit length' : 1 })

        Region0FlashErr.help = """An error occurred attempting to read Region 0 of SPI memory. A retry may have been successful."""
        self.dataModel.addChild(Region0FlashErr)

        Region1FlashErr = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Region 1 Flash Error',
                                                                     'offset' : 9,
                                                                     'bit length' : 1 })

        Region1FlashErr.help = """An error occurred attempting to read Region 1 of SPI memory. A retry may have been successful."""
        self.dataModel.addChild(Region1FlashErr)

        PatchDownloadErr = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Reed Solomon Error',
                                                                     'offset' : 10,
                                                                     'bit length' : 1 })

        PatchDownloadErr.help = """Patch Bundle Download Error had occurred."""
        self.dataModel.addChild(PatchDownloadErr)

        uartSizeErr = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'UART CRC Fail',
                                                                     'offset' : 11,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(uartSizeErr)

        Region0CrcFail = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Region 0 CRC Fail',
                                                                     'offset' : 12,
                                                                     'bit length' : 1 })

        Region0CrcFail.help = """CRC of read data from Region 0 of SPI memory failed."""
        self.dataModel.addChild(Region0CrcFail)

        Region1CrcFail = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Region 1 CRC Fail',
                                                                     'offset' : 13,
                                                                     'bit length' : 1 })

        Region1CrcFail.help = """CRC of read data from Region 1 of SPI memory failed."""
        self.dataModel.addChild(Region1CrcFail)

        CustomerOTPInvalid = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'Customer OTP Invalid',
                                                                     'offset' : 14,
                                                                     'bit length' : 1 })

        CustomerOTPInvalid.help = """If set, the OTP Config bytes above are valid."""
        self.dataModel.addChild(CustomerOTPInvalid)

        oaOtpBits = register_class.cHexDMTerminator(self,
                                                                    {'name' : 'I2C OTP Bits',
                                                                     'offset' : 15,
                                                                     'bit length' : 2 })

        self.dataModel.addChild(oaOtpBits)

        acve = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'App Customization Version Error',
                                                                     'offset' : 17,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(acve)

        acle = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'App Customization Length Error',
                                                                     'offset' : 18,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(acle)

        accrc = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'App Customization CRC Check Error',
                                                                     'offset' : 19,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(accrc)

        dbgCtl = register_class.cHexDMTerminator(self,
                                                                    {'name' : 'DBG_CTL Bits',
                                                                     'offset' : 22,
                                                                     'bit length' : 2 })

        self.dataModel.addChild(dbgCtl)

        dbgCtl = register_class.cHexDMTerminator(self,
                                                                    {'name' : 'I2C_ADDR Bits',
                                                                     'offset' : 24,
                                                                     'bit length' : 3 })

        self.dataModel.addChild(dbgCtl)

        uart = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'UART Boot',
                                                                     'offset' : 27,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(uart)

        uartOv = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'UART Overflow Error',
                                                                     'offset' : 28,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(uartOv)

        pphv = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'PP_HV Switch Closed',
                                                                     'offset' : 29,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(pphv)

        uartRet = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'UART Retry Error',
                                                                     'offset' : 30,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(uartRet)

        uartTime = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'UART Timeout Error',
                                                                     'offset' : 31,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(uartTime)


        OTPCustomerValid = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Customer OTP Valid',
                                                                     'offset' : 32,
                                                                     'bit length' : 2 })

        OTPCustomerValid.help = """10b indicates valid Customer OTP Area."""
        OTPCustomerValid.setMaxValue(1)
        OTPCustomerValid.setReportList(['Invalid Customer OTP', \
                                 'Valid Customer OTP', \
                                 ])
        self.dataModel.addChild(OTPCustomerValid)

        swdDisable = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'SWD Disabled',
                                                                     'offset' : 33,
                                                                     'bit length' : 1 })
        self.dataModel.addChild(swdDisable)

        vout3V3 = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Vout3V3 Control',
                                                                     'offset' : 35,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(vout3V3)

        vout3V3 = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Wait for Vin3V3',
                                                                     'offset' : 36,
                                                                     'bit length' : 1 })

        self.dataModel.addChild(vout3V3)


        OTPcustomerTBTpresent = register_class.cBooleanDMTerminator(self,
                                                                    {'name' : 'OTP Customer TBT Present',
                                                                     'offset' : 47,
                                                                     'bit length' : 1 })

        OTPcustomerTBTpresent.help = """TBT Supported"""
        self.dataModel.addChild(OTPcustomerTBTpresent)

        vout3V3threshold = register_class.cHexDMTerminator(self,
                                                                    {'name' : 'OTP Customer I2C Threshold',
                                                                     'offset' : 50,
                                                                     'bit length' : 5 })

        self.dataModel.addChild(vout3V3threshold)

        REV_ID_Metal = register_class.cHexDMTerminator(self,
                                                                    {'name' : 'Revision ID Metal',
                                                                     'offset' : 64,
                                                                     'bit length' : 4 })

        REV_ID_Metal.help = """PD Controller Silicon (Metal) Revision"""
        self.dataModel.addChild(REV_ID_Metal)

        REV_ID_Base = register_class.cHexDMTerminator(self,
                                                                    {'name' : 'Revision ID Base',
                                                                     'offset' : 68,
                                                                     'bit length' : 4 })

        REV_ID_Base.help = """PD Controller Silicon (Base) Revision, 0001b = A"""
        self.dataModel.addChild(REV_ID_Base)


class cBuildID_0x2E_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Build Identifier',
                                                 'address' : 0x2E,
                                                 'byte length' : 49,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Build Identifier',
                                                        'offset' : 0,
                                                        'bit length' : 392 })
        BuildID = register_class.cAsciiDMTerminator(self,
                                                        {'name' : 'Build Identifier',
                                                         'offset' : 0,
                                                         'bit length' : 392 })
        BuildID.help = """ASCII string returns uniquely identifying custom build information. note: 40 Hex Characters representing the build + 1
underscore character + MMDDYYYY (build date) + null terminator (0).Returns 0 length on released firmware."""
        self.dataModel.addChild(BuildID)


class cDeviceInfo_0x2F_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Device Info',
                                                 'address' : 0x2F,
                                                 'byte length' : 47,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Device Info',
                                                        'offset' : 0,
                                                        'bit length' : 376 })
        DeviceInfo = register_class.cAsciiDMTerminator(self,
                                                        {'name' : 'Device Info',
                                                         'offset' : 0,
                                                         'bit length' : 376 })
        DeviceInfo.help = """ASCII string with hardware and firmware version information of the PD Controller. Note: After NULL terminator for C string there are 12 additional
bytes, returning the same data as the bootloader does for registers
0x00, 0x01 and 0x0F in that order. This makes it possible to
positively identify n PD Controller and its bootloader version even
when the application image has overridden the base registers. This
is necessary for in-system flashing."""
        self.dataModel.addChild(DeviceInfo)



# display pdos based on numPdo
# not a method, but should be grouped with txSrcCap class
def RxSrcCap_TopLevelDMGenerator(self) :
    numSrcPdo = self.getChildByName('Number of Source PDOs').valueToInt()
    retDict = {'name' : self.name, 'grouping tier' : self.tier, 'data model list' : []  }
    retDict['data model list'].append(self.getChildByName('Number of Source PDOs').dataModelGenerator())
    for i in range(numSrcPdo) :
        retDict['data model list'].append(self.getChildByName('Source PDO %d' %(i+1)).dataModelGenerator())

    return retDict

class cRxSrcCap_0x30_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Received Source Capabilities',
                                                 'address' : 0x30,
                                                 'byte length' : 29,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Received Source Capabilities',
                                                        'offset' : 0,
                                                        'bit length' : 232 })


        numSrcPdo = register_class.cDecimalDMTerminator(self,
                                                                  {'name' : 'Number of Source PDOs',
                                                                   'offset' : 0,
                                                                   'bit length' : 3 })

        numSrcPdo.help = """Number of valid Source PDOs that will be transmitted to the sink at the other end of the USB Type-C cable using USB-PD protocol. The PD Controller can transmit between 0 and 7 Source PDOs"""
        numSrcPdo.updateRegisters.append(self)

        self.dataModel.addChild(numSrcPdo)

        sPdo1 = cDMSourcePdo1Array(self, 1, {'name' : 'Source PDO 1',
                                                    'offset' : 8,
                                                    'bit length' : 32,
                                                     'Is Receive' : True })
        self.dataModel.addChild(sPdo1)

        for i in range(2,8) :
            SrcPDOX = cDMAnySourcePdoArray(self, 1,
                                           {'name' : 'Source PDO %d' %i,
                                            'offset' : 8 + ( (i-1) * 32 ),
                                            'bit length' : 32 })

            self.dataModel.addChild(SrcPDOX)

        self.dataModel.setDataModelGenerator(RxSrcCap_TopLevelDMGenerator)



# display pdos based on numPdo
# not a method, but should be grouped with txSrcCap class
def RxSinkCap_TopLevelDMGenerator(self) :
    numSrcPdo = self.getChildByName('Number of Sink PDOs').valueToInt()
    retDict = {'name' : self.name, 'grouping tier' : self.tier, 'data model list' : []  }
    retDict['data model list'].append(self.getChildByName('Number of Sink PDOs').dataModelGenerator())
    for i in range(numSrcPdo) :
        retDict['data model list'].append(self.getChildByName('Sink PDO %d' %(i+1)).dataModelGenerator())

    return retDict

class cRxSinkCap_0x31_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Received Sink Capabilities',
                                                 'address' : 0x31,
                                                 'byte length' : 57,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Received Sink Capabilities',
                                                        'offset' : 0,
                                                        'bit length' : 456 })

        numSinkTerm = register_class.cDecimalDMTerminator(self,
                                                          {'name' : 'Number of Sink PDOs',
                                                           'offset' : 0,
                                                           'bit length' : 3 })
        numSinkTerm.help = """Number of valid sink PDOs that will be transmitted to the source at the other end of the USB Type-C cable using USB-PD protocol. The PD Controller can transmit between 0 and 7 Sink PDOs."""
        numSinkTerm.updateRegisters.append(self)

        # TODO: set max allowable value to 6 (instead of 0-7 from 3 bits)
        self.dataModel.addChild(numSinkTerm)

        sPdo1 = cDMSinkPdo1Array(self, 1, {'name' : 'Sink PDO 1',
                                        'offset' : 8,
                                        'bit length' : 32,
                                        'Is Receive' : True })

        self.dataModel.addChild(sPdo1)
        # need to figure out a more consistent approach, but can't initialize the value until it is placed in register
        sPdo1.getChildByName('Voltage').setFromInt(100)
        sPdo1.getChildByName('Supply Type').setFromInt(0)

        for i in range(2,7) :
            SnkPDOX = cDMAnySinkPdoArray(self, 1,
                                           {'name' : 'Sink PDO %d' %i,
                                            'offset' : 8 + ( (i-1) * 32 ),
                                            'bit length' : 32,
                                            'No RDO Extensions' : True })

            self.dataModel.addChild(SnkPDOX)

        self.dataModel.setDataModelGenerator(RxSinkCap_TopLevelDMGenerator)




# display pdos based on numPdo
# not a method, but should be grouped with txSrcCap class
def TxSrcCap_TopLevelDMGenerator(self) :
    numSrcPdo = self.getChildByName('Tx Source PDO Config').getChildByName('Number of Source PDOs').valueToInt()

    for i in range(7) :
        if i < numSrcPdo :
            self.getChildByName('Source PDO %d' %(i+1)).unhide()
        else :
            self.getChildByName('Source PDO %d' %(i+1)).hide()

    return self.childrenAsListDMGenerator()

def TxSinkCap_TopLevelDMGenerator(self) :
    numSinkPdo = self.getChildByName('Sink PDO Count').getChildByName('Number of Sink PDOs').valueToInt()

    for i in range(7) :
        if i < numSinkPdo :
            self.getChildByName('Sink PDO %d' %(i+1)).unhide()
        else :
            self.getChildByName('Sink PDO %d' %(i+1)).hide()

    return self.childrenAsListDMGenerator()



# four arguments:
# [0] PP_5V configuration
# [1] PP_HV configuration
# [2] PP_EXT configuration
# [3] Number of PDOs
def switchSourcePDO1CheckFxn(self, argumentList, newValue) :
    pp_5v = argumentList[0].valueToInt()
    pp_hv = argumentList[1].valueToInt()
    pp_ext = argumentList[2].valueToInt()
    numPDO = argumentList[3].valueToInt()

    if numPDO == 0 :
        return {'check failed' : False, \
                'message' : None, \
                'change list' : None, \
               }


    switchSetting_options_list = [ 'Internal 5 volt Power Path (PP_5V)', \
                                  'Internal High Voltage Power Path (PP_HV)', \
                                  'Internal 5 volt Power Path (PP_5V)', \
                                  'External High Voltage Power Path (PP_HVE)' \
                                 ]

    pp_5v_options_list = ['PP_5V0 switch not used (disabled)', \
                          'PP_5V0 switch configured for output', \
                         ]

    pp_HV_options_list = ['PP_HV switch not used (disabled)', \
                          'PP_HV switch configured for output', \
                          'PP_HV switch configured for input', \
                          'PP_HV switch configured for input, wait for SYS_RDY command', \
                         ]

    pp_EXT_options_list = ['PP_EXT not used (disabled)', \
                           'PP_EXT configured for output', \
                           'PP_EXT configured for input', \
                           'PP_EXT configured for input, wait for SYS_RDY command', \
                           'PP_EXT configured for input and output', \
                           'PP_EXT configured for input and output, wait for SYS_RDY command', \
                          ]

    if switchSetting_options_list[newValue] == 'Internal 5 volt Power Path (PP_5V)' :
        if pp_5v_options_list[pp_5v] == 'PP_5V0 switch configured for output' :
            return {'check failed' : False, \
                    'message' : None, \
                    'change list' : None, \
                   }
        else :
            return {'check failed' : True, \
                    'message' : 'Setting Transmit Source Capabilities PDO switch source to PP_5V requires that this switch be configured as an output in the System Configuration register.  Currently it is configured as: %s' %pp_5v_options_list[pp_5v], \
                    'change list' : [{'object' : argumentList[0], \
                                      'valid setting list' : [{'value': 1, 'description': pp_5v_options_list[1] },] \
                                     }], \
                   }
    elif switchSetting_options_list[newValue] == 'Internal High Voltage Power Path (PP_HV)' :
        if pp_HV_options_list[pp_hv] == 'PP_HV switch configured for output' :
            return {'check failed' : False, \
                    'message' : None, \
                    'change list' : None, \
                   }
        else :
            return {'check failed' : True, \
                    'message' : 'Setting Transmit Source Capabilities PDO switch source to PP_HV requires that this switch be configured as an output in the System Configuration register.  Currently it is configured as: %s' %pp_HV_options_list[pp_hv], \
                    'change list' : [{'object' : argumentList[1], \
                                      'valid setting list' : [{'value': 1, 'description': pp_HV_options_list[1] },] \
                                     }], \
                   }
    elif switchSetting_options_list[newValue] == 'External High Voltage Power Path (PP_HVE)' :
        if (pp_EXT_options_list[pp_ext] == 'PP_EXT configured for output') \
            or (pp_EXT_options_list[pp_ext] == 'PP_EXT configured for input and output') \
            or (pp_EXT_options_list[pp_ext] == 'PP_EXT configured for input and output, wait for SYS_RDY command' ):

            return {'check failed' : False, \
                    'message' : None, \
                    'change list' : None, \
                   }
        else :
            return {'check failed' : True, \
                    'message' : 'Setting Transmit Source Capabilities PDO switch source to PP_HVE requires that this switch be configured as an output in the System Configuration register.  Currently it is configured as: %s' %pp_EXT_options_list[pp_ext], \
                    'change list' : [{'object' : argumentList[2], \
                                      'valid setting list' : [{'value': 1, 'description': pp_EXT_options_list[1] }, \
                                        {'value': 4, 'description': pp_EXT_options_list[4] },
                                        {'value': 5, 'description': pp_EXT_options_list[5] },
                                      ] \
                                     }], \
                   }
    else :
        return {'check failed' : True, \
                'message' : 'Unknown input option to switchSourceCheckFxn', \
                'change list' : [{'object' : None, \
                                  'valid setting list' : None \
                                 }], \
               }




# three arguments:
# [0] PP_5V configuration
# [1] PP_HV configuration
# [2] PP_EXT configuration
# [3] Number of PDOs
def switchSourceCheckFxn(self, argumentList, newValue) :
    pp_5v = argumentList[0].valueToInt()
    pp_hv = argumentList[1].valueToInt()
    pp_ext = argumentList[2].valueToInt()
    numPDO = argumentList[3].valueToInt()

    if numPDO < self.pdoNumber :
        return {'check failed' : False, \
                'message' : None, \
                'change list' : None, \
               }

    switchSetting_options_list = ['Internal High Voltage Power Path (PP_HV)', \
                                  'External High Voltage Power Path (PP_HVE)' \
                                 ]

    pp_5v_options_list = ['PP_5V0 switch not used (disabled)', \
                          'PP_5V0 switch configured for output', \
                         ]

    pp_HV_options_list = ['PP_HV switch not used (disabled)', \
                          'PP_HV switch configured for output', \
                          'PP_HV switch configured for input', \
                          'PP_HV switch configured for input, wait for SYS_RDY command', \
                         ]

    pp_EXT_options_list = ['PP_EXT not used (disabled)', \
                           'PP_EXT configured for output', \
                           'PP_EXT configured for input', \
                           'PP_EXT configured for input, wait for SYS_RDY command', \
                           'PP_EXT configured for input and output', \
                           'PP_EXT configured for input and output, wait for SYS_RDY command', \
                          ]

    if switchSetting_options_list[newValue] == 'Internal High Voltage Power Path (PP_HV)' :
        if pp_HV_options_list[pp_hv] == 'PP_HV switch configured for output' :
            return {'check failed' : False, \
                    'message' : None, \
                    'change list' : None, \
                   }
        else :
            return {'check failed' : True, \
                    'message' : 'Setting Transmit Source Capabilities PDO switch source to PP_HV requires that this switch be configured as an output in the System Configuration register.  Currently it is configured as: %s' %pp_HV_options_list[pp_hv], \
                    'change list' : [{'object' : argumentList[1], \
                                      'valid setting list' : [{'value': 1, 'description': pp_HV_options_list[1] },] \
                                     }], \
                   }
    elif switchSetting_options_list[newValue] == 'External High Voltage Power Path (PP_HVE)' :
        if (pp_EXT_options_list[pp_ext] == 'PP_EXT configured for output') \
            or (pp_EXT_options_list[pp_ext] == 'PP_EXT configured for input and output') \
            or (pp_EXT_options_list[pp_ext] == 'PP_EXT configured for input and output, wait for SYS_RDY command' ):

            return {'check failed' : False, \
                    'message' : None, \
                    'change list' : None, \
                   }
        else :
            return {'check failed' : True, \
                    'message' : 'Setting Transmit Source Capabilities PDO switch source to PP_HVE requires that this switch be configured as an output in the System Configuration register.  Currently it is configured as: %s' %pp_EXT_options_list[pp_ext], \
                    'change list' : [{'object' : argumentList[2], \
                                      'valid setting list' : [{'value': 1, 'description': pp_EXT_options_list[1] }, \
                                        {'value': 4, 'description': pp_EXT_options_list[4] },
                                        {'value': 5, 'description': pp_EXT_options_list[5] },
                                      ] \
                                     }], \
                   }
    else :
        return {'check failed' : True, \
                'message' : 'Unknown input option to switchSourceCheckFxn', \
                'change list' : [{'object' : None, \
                                  'valid setting list' : None \
                                 }], \
               }



class cTxSrcCap_0x32_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Transmit Source Capabilities',
                                                 'address' : 0x32,
                                                 'byte length' : 31,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Transmit Source Capabilities',
                                                        'offset' : 0,
                                                        'bit length' : 248 })

        SrcPdoConfig = register_class.cDataModelArray(self, 1,
                                                      {'name' : 'Tx Source PDO Config',
                                                        'offset' : 0,
                                                        'bit length' : 24 })

        self.dataModel.addChild(SrcPdoConfig)

        numSrcPdo = register_class.cDecimalDMTerminator(self,
                                                                  {'name' : 'Number of Source PDOs',
                                                                   'offset' : 0,
                                                                   'bit length' : 3 })

        numSrcPdo.addUpdateRegisterByName('self')

        SrcPdoConfig.addChild(numSrcPdo)

        switchDict = { 0 : 'Internal 5 volt Power Path (PP_5V)',
                       1 : 'Internal High Voltage Power Path (PP_HV)',
                       3 : 'External High Voltage Power Path (PP_HVE)'}

        switchReplaceDict = {2 : 0}

        SrcPDO1SwitchSource = register_class.cDictDMTerminator(self,
                                                      {'name' : 'Switch Source',
                                                        'offset' : 0,
                                                        'bit length' : 2 })

        SrcPDO1SwitchSource.setReportDict(switchDict)
        SrcPDO1SwitchSource.setReplaceDict(switchReplaceDict)

        SrcPDO1SwitchSource.setFixedOffset(16)


        sPdo1 = cDMSourcePdo1Array(self, 1, {'name' : 'Source PDO 1',
                                                    'offset' : 24,
                                                    'bit length' : 32 })

        sPdo1.prependChild(SrcPDO1SwitchSource)
        self.dataModel.addChild(sPdo1)
        # need to figure out a more consistent approach, but can't initialize the value until it is placed in register
        sPdo1.getChildByName('Voltage').setFromInt(100)
        sPdo1.getChildByName('Supply Type').setFromInt(0)

        SrcPDO1SwitchSource.registerAsCheckedField(switchSourcePDO1CheckFxn,
             [ \
                ['System Configuration', 'PP_5V0 Configuration'], \
                ['System Configuration', 'PP_HV Configuration'], \
                ['System Configuration', 'PP_EXT Configuration'], \
                ['self', 'Tx Source PDO Config', 'Number of Source PDOs'], \
             ])


        for i in range(2,8) :
            SrcPDOX = cDMAnySourcePdoArray(self, 1,
                                           {'name' : 'Source PDO %d' %i,
                                            'offset' : 24 + ( (i-1) * 32 ),
                                            'bit length' : 32 })

            SrcPDOXAdvertised = register_class.cListDMTerminator( self,
                                                                  {'name' : 'Advertised Mask',
                                                                   'offset' : 0,
                                                                   'bit length' : 1})

            SrcPDOXAdvertised.setReportList(['Advertise only if Externally Powered', 'Always Advertise'])
            SrcPDOXAdvertised.setFixedOffset(8 + i)

            SrcPDOXSwitchSource = register_class.cListDMTerminator( self,
                                                                    {'name' : 'Switch Source',
                                                                     'offset' : 0,
                                                                     'bit length' : 1})

            SrcPDOXSwitchSource.setReportList(['Internal High Voltage Power Path (PP_HV)', 'External High Voltage Power Path (PP_HVE)'])
            SrcPDOXSwitchSource.setFixedOffset(16 + i)

            SrcPDOXSwitchSource.pdoNumber = i

            SrcPDOXSwitchSource.registerAsCheckedField(switchSourceCheckFxn,
                 [ \
                    ['System Configuration', 'PP_5V0 Configuration'], \
                    ['System Configuration', 'PP_HV Configuration'], \
                    ['System Configuration', 'PP_EXT Configuration'], \
                    ['self', 'Tx Source PDO Config', 'Number of Source PDOs'], \
                 ])

            SrcPDOX.prependChild(SrcPDOXSwitchSource)
            SrcPDOX.prependChild(SrcPDOXAdvertised)

            self.dataModel.addChild(SrcPDOX)

        self.dataModel.setDataModelGenerator(TxSrcCap_TopLevelDMGenerator)


class cTxSinkCap_0x33_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Transmit Sink Capabilities',
                                                 'address' : 0x33,
                                                 'byte length' : 57,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Transmit Sink Capabilities',
                                                        'offset' : 0,
                                                        'bit length' : 456 })

        SrcPdoConfig = register_class.cDataModelArray(self, 1,
                                                      {'name' : 'Sink PDO Count',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        self.dataModel.addChild(SrcPdoConfig)

        numSinkTerm = register_class.cDecimalDMTerminator(self,
                                                          {'name' : 'Number of Sink PDOs',
                                                           'offset' : 0,
                                                           'bit length' : 3 })
        numSinkTerm.addUpdateRegisterByName('self')

        SrcPdoConfig.addChild(numSinkTerm)

        sPdo1 = cDMSinkPdo1Array(self, 1, {'name' : 'Sink PDO 1',
                                        'offset' : 8,
                                        'bit length' : 32 })

        self.dataModel.addChild(sPdo1)
        # need to figure out a more consistent approach, but can't initialize the value until it is placed in register
        sPdo1.getChildByName('Voltage').setFromInt(100)
        sPdo1.getChildByName('Supply Type').setFromInt(0)

        for i in range(2,8) :
            SnkPDOX = cDMAnySinkPdoArray(self, 1,
                                           {'name' : 'Sink PDO %d' %i,
                                            'offset' : 8 + ( (i-1) * 32 ),
                                            'bit length' : 32 })

            self.dataModel.addChild(SnkPDOX)

        self.dataModel.setDataModelGenerator(TxSinkCap_TopLevelDMGenerator)



class cActiveContractPDO_0x34_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Active Contract PDO',
                                                 'address' : 0x34,
                                                 'byte length' : 4,
                                                 'permission' : 'DRO'})

        activePDO = cDMAnySourcePdoArray(self, 1,
                                       {'name' : 'Active Contract PDO',
                                        'offset' : 0 ,
                                        'bit length' : 32 })


        self.dataModel = activePDO


########################################################################################################################
########################################################################################################################
########################################################################################################################

class cActiveContractRDO_0x35_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Active Contract RDO',
                                                 'address' : 0x35,
                                                 'byte length' : 4,
                                                 'permission' : 'DRO'})
                                                 #E.B. Not sure if RO or DO?

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Active Contract RDO',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        #E.B. Not sure how to populate this register (0x35) Active Contract RDO.

        maxOpCurrent = cPDOCurrentField( self,  { 'name' : 'Max/Min Operating Current',
                                                                'offset' : 0,
                                                                'bit length' : 10})

        self.dataModel.addChild(maxOpCurrent)

        operatingCurrent = cPDOCurrentField( self,  { 'name' : 'Operating Current',
                                                                'offset' : 10,
                                                                'bit length' : 10})

        self.dataModel.addChild(operatingCurrent)

        noUsbSuspend = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'No USB Suspend',
                                                           'offset' : 24,
                                                           'bit length' : 1 })

        self.dataModel.addChild( noUsbSuspend )

        usbCommCap = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'USB Communication Capable',
                                                           'offset' : 25,
                                                           'bit length' : 1 })

        self.dataModel.addChild( usbCommCap )

        capMismatch = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'Capability Mismatch',
                                                           'offset' : 26,
                                                           'bit length' : 1 })

        self.dataModel.addChild( capMismatch )

        giveback = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'Giveback Flag',
                                                           'offset' : 27,
                                                           'bit length' : 1 })

        self.dataModel.addChild( giveback )

        giveback = register_class.cDecimalDMTerminator(self,
                                                          {'name' : 'Object Position',
                                                           'offset' : 28,
                                                           'bit length' : 3 })

        self.dataModel.addChild( giveback )


########################################################################################################################
########################################################################################################################
########################################################################################################################

class cSinkRequestRDO_0x36_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Sink Request RDO',
                                                 'address' : 0x36,
                                                 'byte length' : 4,
                                                 'permission' : 'DRO'})
                                                 #E.B. Not sure if RO or DO?

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Sink Request RDO',
                                                        'offset' : 0,
                                                        'bit length' : 32 })
        #E.B. Not sure how to populate this register (0x36) Active Contract RDO.

        maxOpCurrent = cPDOCurrentField( self,  { 'name' : 'Max/Min Operating Current',
                                                                'offset' : 0,
                                                                'bit length' : 10})

        self.dataModel.addChild(maxOpCurrent)

        operatingCurrent = cPDOCurrentField( self,  { 'name' : 'Operating Current',
                                                                'offset' : 10,
                                                                'bit length' : 10})

        self.dataModel.addChild(operatingCurrent)

        noUsbSuspend = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'No USB Suspend',
                                                           'offset' : 24,
                                                           'bit length' : 1 })

        self.dataModel.addChild( noUsbSuspend )

        usbCommCap = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'USB Communication Capable',
                                                           'offset' : 25,
                                                           'bit length' : 1 })

        self.dataModel.addChild( usbCommCap )

        capMismatch = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'Capability Mismatch',
                                                           'offset' : 26,
                                                           'bit length' : 1 })

        self.dataModel.addChild( capMismatch )

        giveback = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'Giveback Flag',
                                                           'offset' : 27,
                                                           'bit length' : 1 })

        self.dataModel.addChild( giveback )

        giveback = register_class.cDecimalDMTerminator(self,
                                                          {'name' : 'Object Position',
                                                           'offset' : 28,
                                                           'bit length' : 3 })

        self.dataModel.addChild( giveback )



def ANEGSinkDMGenerator(self) :
    autoCalc = self.getChildByName('Capabilities Mismatch Determination').getChildByName('Automatically Calculate Min Power Required').valueToInt()
    minPow = self.getChildByName('Capabilities Mismatch Determination').getChildByName('Minimum Power Required')

    if autoCalc == 1 :
        minPow.hide()
    else :
        minPow.unhide()

    return self.childrenAsListDMGenerator()



class cAutoNegSink_0x37_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Autonegotiate Sink',
                                                 'address' : 0x37,
                                                 'byte length' : 12,
                                                 'permission' : 'RW'})

        self.FORCESETAUTONEG = False

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Autonegotitate Sink',
                                                        'offset' : 0,
                                                        'bit length' : 96 })

        genSetting = register_class.cDataModelArray(self, 1,
                                                      {'name' : 'General Settings',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        self.dataModel.addChild(genSetting)

        autoNegSink = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'Autonegotiate Sink Enable',
                                                           'offset' : 0,
                                                           'bit length' : 1 })

        if self.FORCESETAUTONEG == True :
            autoNegSinkForce = register_class.cForceSetDMTerminator(self,
                                                              {'name' : 'Autonegotiate Sink Enable',
                                                               'offset' : 0,
                                                               'bit length' : 1,
                                                               'force value' : int(1),
                                                               'force display' : 'Enabled',
                                                               'display widget' : autoNegSink })
            genSetting.addChild(autoNegSinkForce)
            autoNegSinkForce.setFromInt(1)
        else :
            genSetting.addChild(autoNegSink)

        autoNegVarSink = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'Autonegotiate Variable Sink Enable',
                                                           'offset' : 1,
                                                           'bit length' : 1 })

        if self.FORCESETAUTONEG == True :
            autoNegVarSinkForce = register_class.cForceSetDMTerminator(self,
                                                              {'name' : 'Autonegotiate Variable Sink Enable',
                                                               'offset' : 1,
                                                               'bit length' : 1,
                                                               'force value' : int(1),
                                                               'force display' : 'Enabled',
                                                               'display widget' : autoNegVarSink })
            genSetting.addChild(autoNegVarSinkForce)
            autoNegVarSinkForce.setFromInt(1)
        else :
            genSetting.addChild(autoNegVarSink)


        autoNegBatSink = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'Autonegotiate Battery Sink Enable',
                                                           'offset' : 2,
                                                           'bit length' : 1 })

        if self.FORCESETAUTONEG == True :
            autoNegBatSinkForce = register_class.cForceSetDMTerminator(self,
                                                              {'name' : 'Autonegotiate Battery Sink Enable',
                                                               'offset' : 2,
                                                               'bit length' : 1,
                                                               'force value' : int(1),
                                                               'force display' : 'Enabled',
                                                               'display widget' : autoNegBatSink })
            genSetting.addChild(autoNegBatSinkForce)
            autoNegBatSinkForce.setFromInt(1)
        else :
            genSetting.addChild(autoNegBatSink)


        USBCommCap = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'USB Communication Capable',
                                                           'offset' : 3,
                                                           'bit length' : 1 })

        genSetting.addChild(USBCommCap)

        offerPri = register_class.cListDMTerminator(self,
                                                          {'name' : 'Offer Priority',
                                                           'offset' : 4,
                                                           'bit length' : 2 })

        offerPri.setReportList(['Choose Highest Current', 'Choose Highest Voltage', 'Choose Highest Power'])

        genSetting.addChild(offerPri)

        noUsbSusp = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'No USB Suspend',
                                                           'offset' : 6,
                                                           'bit length' : 1 })

        genSetting.addChild(noUsbSusp)

        giveBack = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'Giveback Flag',
                                                           'offset' : 7,
                                                           'bit length' : 1 })

        genSetting.addChild(giveBack)

        anegPower = register_class.cDataModelArray(self, 1,
                                                      {'name' : 'Capabilities Mismatch Determination',
                                                        'offset' : 8,
                                                        'bit length' : 24 })

        self.dataModel.addChild(anegPower)


        autoMinPowReq = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'Automatically Calculate Min Power Required',
                                                        'offset' : 0,
                                                        'bit length' : 1 })

        autoMinPowReq.addUpdateRegisterByName("self")
        anegPower.addChild(autoMinPowReq)

        minPowerReq = cPDOPowerField(self,
                                                          {'name' : 'Minimum Power Required',
                                                           'offset' : 8,
                                                           'bit length' : 10 })

        minPowerReq.addUpdateRegisterByName("self")
        anegPower.addChild(minPowerReq)

        self.dataModel.setDataModelGenerator(ANEGSinkDMGenerator)



class cAltModeQueueRecord(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        svid = register_class.cHexDMTerminator(self.register,
                                                      {'name' : 'SVID (Standard or Vendor ID)',
                                                        'offset' : 0,
                                                        'bit length' : 16 })

        self.addChild(svid)

        objpos = register_class.cHexDMTerminator(self.register,
                                                      {'name' : 'Mode Number',
                                                        'offset' : 16,
                                                        'bit length' : 8 })

        self.addChild(objpos)

class cAltModeEntryQueue_0x38_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Alternate Mode Entry Queue',
                                                 'address' : 0x38,
                                                 'byte length' : 12,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Alternate Mode Entry Queue',
                                                        'offset' : 0,
                                                        'bit length' : 96 })

        for i in range(3) :

            numSinkTerm = cAltModeQueueRecord(self, 1,
                                                              {'name' : 'Alternate Mode Entry Queue record #%d' %(i+1),
                                                               'offset' : 32 * i,
                                                               'bit length' : 32 })

            self.dataModel.addChild(numSinkTerm)


class cPowerStatus_0x3F_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Power Status',
                                                 'address' : 0x3F,
                                                 'byte length' : 2,
                                                 'permission' : 'DRO'})
                                                 #E.B. Not sure if this should be RO or DO?

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Power Status',
                                                        'offset' : 0,
                                                        'bit length' : 16 })

        PowerConnection = register_class.cListDMTerminator(self,
                                                          {'name' : 'Offer Priority',
                                                           'offset' : 0,
                                                           'bit length' : 1 })

        PowerConnection.help = """1b when a connection is present. 0b when there is no connection to the PD Controller."""
        PowerConnection.setReportList(['No Connection', 'Connection Present'])
        self.dataModel.addChild(PowerConnection)

        SourceSink = register_class.cListDMTerminator(self,
                                                          {'name' : 'Source or Sink',
                                                           'offset' : 1,
                                                           'bit length' : 1 })

        SourceSink.help = """1b connection provides power (PD Controller as Sink). 0b connection requests power (PD Controller as Source)."""
        SourceSink.setReportList(['Source', 'Sink'])
        self.dataModel.addChild(SourceSink)

        TypeCCurrent = register_class.cListDMTerminator(self,
                                                          {'name' : 'Type-C Current',
                                                           'offset' : 2,
                                                           'bit length' : 2 })

        TypeCCurrent.help = """1b connection provides power (PD Controller as Sink). 0b connection requests power (PD Controller as Source)."""
        TypeCCurrent.setReportList(['USB Default Current', '1.5A Current', '3A Current', 'PD Contract Negotiated'])
        self.dataModel.addChild(TypeCCurrent)

        BC12Detection = register_class.cListDMTerminator(self,
                                                          {'name' : 'BC 1.2 Detection',
                                                           'offset' : 4,
                                                           'bit length' : 1 })

        BC12Detection.help = """Determines if a BC 1.2 connection has been established on the Type-C port."""
        BC12Detection.setReportList(['USB BC v1.2 connection not yet established', 'USB BC v1.2 connection valid'])
        self.dataModel.addChild(BC12Detection)

        BC12Status = register_class.cListDMTerminator(self,
                                                          {'name' : 'BC 1.2 Status',
                                                           'offset' : 5,
                                                           'bit length' : 2 })

        BC12Status.help = """Displays the status of the BC1.2 Connection."""
        BC12Status.setReportList(['SDP Detected', 'Reserved', 'CDP Detected', 'DCP Detected'])
        self.dataModel.addChild(BC12Status)


########################################################################################################################
########################################################################################################################
########################################################################################################################

class cPDStatus_0x40_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'PD Status',
                                                 'address' : 0x40,
                                                 'byte length' : 4,
                                                 'permission' : 'DRO'})
                                                 #E.B. Not sure if this should be RO or DO?

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'PD Status',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        PlugDetails = register_class.cListDMTerminator(self,
                                                          {'name' : 'Plug Details',
                                                           'offset' : 0,
                                                           'bit length' : 2 })

        PlugDetails.help = """Displays details of the Type-C Plug."""
        PlugDetails.setReportList(['USB Type-C full-featured plug', 'USB 2.0 Type-C plug'])
        PlugDetails.setMaxValue(1)
        self.dataModel.addChild(PlugDetails)

        CCPullUp = register_class.cListDMTerminator(self,
                                                          {'name' : 'CC Pull-up',
                                                           'offset' : 2,
                                                           'bit length' : 2 })

        CCPullUp.help = """CC Pull-up value detected by PD Controller when in CC Pull-down mode"""
        CCPullUp.setReportList(['Not in CC pull-down mode / no CC pull-up detected.', 'USB Default Current', '1.5A Current', '3A Current'])
        CCPullUp.setMaxValue(3)
        self.dataModel.addChild(CCPullUp)

        PortType = register_class.cListDMTerminator(self,
                                                          {'name' : 'Port Type',
                                                           'offset' : 4,
                                                           'bit length' : 2 })

        PortType.help = """The PD Sink/Source role PD Controller is acting under."""
        PortType.setReportList(['Sink/Source', 'Sink', 'Source', 'Source/Sink'])
        PortType.setMaxValue(3)
        self.dataModel.addChild(PortType)

        PresentRole = register_class.cListDMTerminator(self,
                                                          {'name' : 'Present Role',
                                                           'offset' : 6,
                                                           'bit length' : 1 })

        PresentRole.help = """The PD source/sink role PD Controller is acting under."""
        PresentRole.setReportList(['Sink', 'Source'])
        PresentRole.setMaxValue(1)
        self.dataModel.addChild(PresentRole)

        SoftResetType = register_class.cListDMTerminator(self,
                                                          {'name' : 'Soft Reset Details',
                                                           'offset' : 8,
                                                           'bit length' : 5 })

        SoftResetType.help = """Displays details as to why a Soft Reset event occurred."""
        SoftResetType.setReportList(['Reset value, no soft reset', \
                                 'Soft reset received from far-end device.', \
                                 'Reserved', \
                                 'Soft reset sent, a GoodCRC was expected but something else was received', \
                                 'Soft reset sent because the received source capabilities message was invalid', \
                                 'Soft reset sent after retries were exhausted.', \
                                 'Soft reset sent due to receiving an accept message unexpectedly.', \
                                 'Reserved', \
                                 'Soft reset sent due to receiving a GetSinkCap message unexpectedly.', \
                                 'Soft reset sent due to receiving a GetSourceCap message unexpectedly.', \
                                 'Soft reset sent due to receiving a GotoMin message unexpectedly', \
                                 'Soft reset sent due to receiving a PS_RDY message unexpectedly.', \
                                 'Soft reset sent due to receiving a Ping message unexpectedly.', \
                                 'Soft reset sent due to receiving a Reject message unexpectedly.', \
                                 'Soft reset sent due to receiving a Request message unexpectedly.', \
                                 'Soft reset sent due to receiving a Sink Capabilities message unexpectedly', \
                                 'Soft reset sent due to receiving a Source Capabilities message unexpectedly', \
                                 'Soft reset sent due to receiving a Swap message unexpectedly.', \
                                 'Soft reset sent due to receiving a Wait Capabilities message unexpectedly', \
                                 'Soft reset sent due to receiving an unknown control message', \
                                 'Soft reset sent due to receiving an unknown data message.', \
                                 'Soft reset sent to initialize SOP’ controller in plug', \
                                 'Soft reset sent to initialize SOP’’ controller in plug', \
                                 ])
        SoftResetType.setMaxValue(23)
        self.dataModel.addChild(SoftResetType)

        HardResetDetails = register_class.cListDMTerminator(self,
                                                          {'name' : 'Hard Reset Details',
                                                           'offset' : 16,
                                                           'bit length' : 6 })

        HardResetDetails.help = """Displays details as to why a Hard Reset event occurred."""
        HardResetDetails.setReportList(['Reset value, no hard reset.', \
                                 'Required by the policy engine (signaling sent by far end).', \
                                 'Requested by host.', \
                                 'Invalid DR_Swap request during Active Mode', \
                                 'Required by policy engine, DischargeFailed', \
                                 'Required by policy engine, NoResponseTimeOut', \
                                 'Required by policy engine, SendSoftReset', \
                                 'Required by policy engine, Sink_SelectCapability.', \
                                 'Required by policy engine, Sink_TransitionSink.', \
                                 'Required by policy engine, Sink_WaitForCapabilities', \
                                 'Required by policy engine, SoftReset.', \
                                 'Required by policy engine, SourceOnTimeout', \
                                 'Required by policy engine, Source_CapabilityResponse', \
                                 'Required by policy engine, Source_SendCapabilities', \
                                 'Required by policy engine, SourcingFault', \
                                 'Required by policy engine, UnableToSource.', \
                                 ])
        HardResetDetails.setMaxValue(23)
        self.dataModel.addChild(HardResetDetails)


########################################################################################################################
########################################################################################################################
########################################################################################################################

class cDPStatus(register_class.cDataModelArray) :
    def __init__ (self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        DUConn_List = ['Neither DFP_D or UFP_D connected', 'DFP_D is connected', 'UFP_D is connected', 'Both DFP_D and UFP_D are connected']
        PowerLow_List = ['Adapter is functioning normally or disabled', 'Adapter has detected low power and DP is disabled']
        DPDisabledEnabled_List = ['DP functionality is Disabled', 'DP functionality is enabled']
        MFPref_List = ['No Preference for Multi-function', 'Multi-function preferred']
        USBConf_List = ['Maintain current configuration', 'Request switch to USB Configuration']
        DPExit_List = ['Maintain current mode', 'Request exit from DisplayPort Mode']
        HPDState_List = ['HPD_Low', 'HPD_High']
        IRQHPD_List = ['No IRQ_HPD since last status', 'IRQ_HPD']


        dDuDconn = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'Connection Status',
                                                        'offset' : 0,
                                                        'bit length' : 2 })

        dDuDconn.setReportList(DUConn_List)
        self.addChild(dDuDconn)

        powLow = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'Power Low',
                                                        'offset' : 2,
                                                        'bit length' : 1 })

        powLow.setReportList(PowerLow_List)
        self.addChild(powLow)

        enabled = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'Enabled',
                                                        'offset' : 3,
                                                        'bit length' : 1 })

        enabled.setReportList(DPDisabledEnabled_List)
        self.addChild(enabled)

        mfp = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'Multi-function Preferred',
                                                        'offset' : 4,
                                                        'bit length' : 1 })

        mfp.setReportList(MFPref_List)
        self.addChild(mfp)

        usbConf = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'USB Configuration Request',
                                                        'offset' : 5,
                                                        'bit length' : 1 })

        usbConf.setReportList(USBConf_List)
        self.addChild(usbConf)

        exitDP = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'Exit DisplayPort Mode Request',
                                                        'offset' : 6,
                                                        'bit length' : 1 })

        exitDP.setReportList(DPExit_List)
        self.addChild(exitDP)

        hpdState = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'HPD State',
                                                        'offset' : 7,
                                                        'bit length' : 1 })

        hpdState.setReportList(HPDState_List)
        self.addChild(hpdState)

        hpdState = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'IRQ HPD',
                                                        'offset' : 8,
                                                        'bit length' : 1 })

        hpdState.setReportList(IRQHPD_List)
        self.addChild(hpdState)

        reserved = register_class.cForceSetDMTerminator( self.register,  { 'name' : "reserved",
                                                                'offset' : 9,
                                                                'bit length' : 23,
                                                                'force value' : int(0),
                                                                'force display' : 'reserved'})

        reserved.setFromInt(0)
        reserved.hide()
        self.addChild(reserved)


class cDPConfig(register_class.cDataModelArray) :
    def __init__ (self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        portCap = register_class.cListDMTerminator(self.register,
                                                        {'name' : 'Select Configuration',
                                                         'offset' : 0,
                                                         'bit length' : 2 })

        portCap.help = """DP Port Capability00b = Reserved01b = UFP_D-capable (including Branch device)10b = DFP_D-capable (including Branch device)11b = Both DFP_D and UFP_D-capable"""
        portCap.setReportList(['Set configuration for USB', 'Set configuration for UFP_U as DFP_D', 'Set configuration for UFP_U as UFP_D', 'Reserved'])

        self.addChild(portCap)

        dpSignalling = register_class.cBooleanDMTerminator(self.register,
                                                        {'name' : 'Supports DP v1.3 signalling',
                                                         'offset' : 2,
                                                         'bit length' : 1 })

        self.addChild(dpSignalling)

        usbSignalling = register_class.cBooleanDMTerminator(self.register,
                                                        {'name' : 'Supports USB Gen 2 signalling',
                                                         'offset' : 3,
                                                         'bit length' : 1 })

        self.addChild(usbSignalling)



        dfpdpins = register_class.cMultiBooleanDMTerminator(self.register,
                                                        {'name' : 'DFPD Receptacle or UFPD Plug Pin Assignment',
                                                         'offset' : 8,
                                                         'bit length' : 8 })
        dfpdpins.help = """Each bit corresponds to an allowed pin assignment. Multiple pin assignments may be allowed.00000000b = DFP pin assignments are not supported.xxxxxxx1b = Pin assignment A is supportedxxxxxx1xb = Pin assignment B is supportedxxxxx1xxb = Pin assignment C is supportedxxxx1xxxb = Pin assignment D is supportedxxx1xxxxb = Pin assignment E is supportedxx1xxxxxb = Pin assignment F is supportedx1xxxxxxb = Reserved1xxxxxxxb = Reserved"""
        dfpdpins.setFlagNameList(['A', 'B', 'C', 'D', 'E', 'F'])
        dfpdpins.setFlagMask([1, 1, 1, 1, 1, 1, 0, 0])
        dfpdpins.setSpacing(6)
        self.addChild(dfpdpins)

        ufpdpins = register_class.cMultiBooleanDMTerminator(self.register,
                                                        {'name' : 'UFPD Receptacle or DFPD Plug Pin Assignment',
                                                         'offset' : 16,
                                                         'bit length' : 8 })
        ufpdpins.help = """Each bit corresponds to an allowed pin assignment. Multiple pin assignments may be allowed.00000000b = UFP pin assignments are not supported.xxxxxxx1b = Pin assignment A is supportedxxxxxx1xb = Pin assignment B is supportedxxxxx1xxb = Pin assignment C is supportedxxxx1xxxb = Pin assignment D is supportedxxx1xxxxb = Pin assignment E is supportedxx1xxxxxb = Reservedx1xxxxxxb = Reserved1xxxxxxxb = Reserved"""
        ufpdpins.setFlagNameList(['A', 'B', 'C', 'D', 'E', 'F'])
        ufpdpins.setFlagMask([1, 1, 1, 1, 1, 0, 0, 0])
        ufpdpins.setSpacing(6)
        self.addChild(ufpdpins)

        reserved = register_class.cForceSetDMTerminator( self.register,  { 'name' : "reserved",
                                                                'offset' : 24,
                                                                'bit length' : 8,
                                                                'force value' : int(0),
                                                                'force display' : 'reserved'})

        reserved.setFromInt(0)
        reserved.hide()
        self.addChild(reserved)


class cDPMode(register_class.cDataModelArray) :
    def __init__ (self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        portCap = register_class.cListDMTerminator(self.register,
                                                        {'name' : 'Port Capability',
                                                         'offset' : 0,
                                                         'bit length' : 2 })

        portCap.help = """DP Port Capability00b = Reserved01b = UFP_D-capable (including Branch device)10b = DFP_D-capable (including Branch device)11b = Both DFP_D and UFP_D-capable"""
        portCap.setReportList(['Reserved', 'UFP_D capable', 'DFP_D capable', 'Both UFP_d and DFP_D capable'])

        self.addChild(portCap)

        dpSignalling = register_class.cBooleanDMTerminator(self.register,
                                                        {'name' : 'Supports DP v1.3 signalling',
                                                         'offset' : 2,
                                                         'bit length' : 1 })

        self.addChild(dpSignalling)

        usbSignalling = register_class.cBooleanDMTerminator(self.register,
                                                        {'name' : 'Supports USB Gen 2 signalling',
                                                         'offset' : 3,
                                                         'bit length' : 1 })

        self.addChild(usbSignalling)


        dfpdpins = register_class.cMultiBooleanDMTerminator(self.register,
                                                        {'name' : 'DFPD Receptacle or UFPD Plug Pin Assignment',
                                                         'offset' : 8,
                                                         'bit length' : 8 })
        dfpdpins.help = """Each bit corresponds to an allowed pin assignment. Multiple pin assignments may be allowed.00000000b = DFP pin assignments are not supported.xxxxxxx1b = Pin assignment A is supportedxxxxxx1xb = Pin assignment B is supportedxxxxx1xxb = Pin assignment C is supportedxxxx1xxxb = Pin assignment D is supportedxxx1xxxxb = Pin assignment E is supportedxx1xxxxxb = Pin assignment F is supportedx1xxxxxxb = Reserved1xxxxxxxb = Reserved"""
        dfpdpins.setFlagNameList(['A', 'B', 'C', 'D', 'E', 'F'])
        dfpdpins.setFlagMask([1, 1, 1, 1, 1, 1, 0, 0])
        dfpdpins.setSpacing(6)
        self.addChild(dfpdpins)

        ufpdpins = register_class.cMultiBooleanDMTerminator(self.register,
                                                        {'name' : 'UFPD Receptacle or DFPD Plug Pin Assignment',
                                                         'offset' : 16,
                                                         'bit length' : 8 })
        ufpdpins.help = """Each bit corresponds to an allowed pin assignment. Multiple pin assignments may be allowed.00000000b = UFP pin assignments are not supported.xxxxxxx1b = Pin assignment A is supportedxxxxxx1xb = Pin assignment B is supportedxxxxx1xxb = Pin assignment C is supportedxxxx1xxxb = Pin assignment D is supportedxxx1xxxxb = Pin assignment E is supportedxx1xxxxxb = Reservedx1xxxxxxb = Reserved1xxxxxxxb = Reserved"""
        ufpdpins.setFlagNameList(['A', 'B', 'C', 'D', 'E', 'F'])
        ufpdpins.setFlagMask([1, 1, 1, 1, 1, 0, 0, 0])
        ufpdpins.setSpacing(6)
        self.addChild(ufpdpins)

        reserved = register_class.cForceSetDMTerminator( self.register,  { 'name' : "reserved",
                                                                'offset' : 24,
                                                                'bit length' : 8,
                                                                'force value' : int(0),
                                                                'force display' : 'reserved'})

        reserved.setFromInt(0)
        reserved.hide()
        self.addChild(reserved)


class cDPSIDStatus_0x58_register(register_class.cRegister) :
    def __init__ (self):
        register_class.cRegister.__init__(self, {'register name' : 'DP SID Status',
                                                 'address' : 0x58,
                                                 'byte length' : 17,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'DP SID Status',
                                                        'offset' : 0,
                                                        'bit length' : 136 })

        DPSIDDetected = register_class.cListDMTerminator(self,
                                                      {'name' : 'DP SID Detected',
                                                        'offset' : 0,
                                                        'bit length' : 1 })
        DPSIDDetected.setReportList(['DP SID not detected', 'Far-end DFP_U has issued DP SID SVDM or UFP_U has responded with ACK'])

        DPSIDDetected.help = """0 (DFP_U/ UFP_U) - DP SID not detected\n\n 1 (DFP_U) - UFP_U returned to DP SID in Discover SVIDs response or responded with ACK to DP SID SVDM Commands\n\n 1 (UFP_U) - DFP_U has issued DP SID SVDM (DIscover Modes, Enter Modes, etc)."""
        self.dataModel.addChild(DPSIDDetected)

        DPModeActive = register_class.cHexDMTerminator(self,
                                                        {'name' : 'DP Mode Active',
                                                         'offset' : 1,
                                                         'bit length' : 1 })
        DPModeActive.help = """0 (DFP_U/ UFP_U) - DP SID not active \n\n1 (DFP_U) - PD Controller has entered DisplayPort Mode with attached UFP_U \n\n1 (UFP-U) - Attached DFP_U has entered DisplayPort Mode"""
        self.dataModel.addChild(DPModeActive)

        errorCode = register_class.cHexDMTerminator(self,
                                                      {'name' : 'Error Code',
                                                        'offset' : 2,
                                                        'bit length' : 3 })
        errorCode.help = """Error Code."""
        self.dataModel.addChild(errorCode)

        DPStatusTX = cDPStatus(self, 1,
                                                        {'name' : 'DP Status TX',
                                                        'offset' : 8,
                                                        'bit length' : 32 })
        DPStatusTX.help = """Current Outgoing DP Status message contents"""
        self.dataModel.addChild(DPStatusTX)

        DPStatusRX = cDPStatus(self, 1,
                                                        {'name' : 'DP Status RX',
                                                        'offset' : 40,
                                                        'bit length' : 32 })
        DPStatusRX.help = """Most recently received DP Status message contents"""
        self.dataModel.addChild(DPStatusRX)

        DPConfigure = cDPConfig(self, 1,
                                                        {'name' : 'DP Configure',
                                                        'offset' : 72,
                                                        'bit length' : 32 })
        DPConfigure.help = """Contents of DP Configure message when sent (DFP_U) or received (UFP_U)."""
        self.dataModel.addChild(DPConfigure)


        DPModeData = cDPMode(self, 1,
                                                        {'name' : 'DP Mode Data',
                                                        'offset' : 104,
                                                        'bit length' : 32 })
        DPModeData.help = """Contents of DP Discover Mode response when received (DFP_U) or sent (UFP_U)."""
        self.dataModel.addChild(DPModeData)

########################################################################################################################
########################################################################################################################
########################################################################################################################


class cTBTEnterMode(register_class.cDataModelArray) :
    def __init__ (self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        TBTCableSpeedSupport = register_class.cListDMTerminator(self.register,
                                                  {'name': 'Thunderbolt Cable Speed Support',
                                                   'offset': 0,
                                                   'bit length': 3})

        TBTCableSpeedSupport.help = """Displays if a power mismatch has occurred."""
        TBTCableSpeedSupport.setReportList(['Reserved', 'USB3.1 gen1 cable (10Gb/s Thunderbolt support)', '10Gb/s only', '10Gb/s & 20Gb/s only'])
        TBTCableSpeedSupport.setMaxValue(3)
        self.addChild(TBTCableSpeedSupport)

        TBTCableGen = register_class.cListDMTerminator(self.register,
                                                  {'name': 'Thunderbolt Cable Gen',
                                                   'offset': 3,
                                                   'bit length': 2})

        TBTCableGen.help = """Displays if a power mismatch has occurred."""
        TBTCableGen.setReportList(['3rd generation TBT (10.3125 and 20.625 Gb/s)', '4th generation TBT (10.0, 10.3125, 20.0 and 20.625 Gb/s)'])
        TBTCableGen.setMaxValue(1)
        self.addChild(TBTCableGen)

        CableType = register_class.cListDMTerminator(self.register,
                                                  {'name': 'Cable Type',
                                                   'offset': 5,
                                                   'bit length': 1})

        CableType.help = """Status of the Thunderbolt Connection."""
        CableType.setReportList(['Type-C to Type-C Cable', 'Legacy Adapter'])
        self.addChild(CableType)

        activeCable = register_class.cListDMTerminator(self.register,
                                                  {'name': 'Active Cable',
                                                   'offset': 6,
                                                   'bit length': 1})

        CableType.help = """Status of the Thunderbolt Connection."""
        CableType.setReportList(['Active Cable', 'Passive Cable'])
        self.addChild(activeCable)

        ActiveLinkTraining = register_class.cListDMTerminator(self.register,
                                                  {'name': 'Active Link Training',
                                                   'offset': 7,
                                                   'bit length': 1})

        ActiveLinkTraining.help = """Status of Active Link Training connection."""
        ActiveLinkTraining.setReportList(['Active with bi-directional LSRX communication (also used for passive cables)', 'Active with uni-directional LSRX communication'])
        self.addChild(ActiveLinkTraining)

        legacy = register_class.cListDMTerminator(self.register,
                                                        {'name' : 'Legacy TBT Adapter',
                                                         'offset' : 8,
                                                         'bit length' : 1 })

        legacy.setReportList(['Is Not a Legacy Adapter', 'Is a Legacy Adapter'])

        self.addChild(legacy)


class cTBTSOPResponse(register_class.cDataModelArray) :
    def __init__ (self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        legacy = register_class.cListDMTerminator(self.register,
                                                        {'name' : 'Legacy TBT Adapter',
                                                         'offset' : 0,
                                                         'bit length' : 1 })

        legacy.setReportList(['Is Not a Legacy Adapter', 'Is a Legacy Adapter'])

        self.addChild(legacy)


class cTBTSOPPrimeResponse(register_class.cDataModelArray) :
    def __init__ (self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        TBTCableSpeedSupport = register_class.cListDMTerminator(self.register,
                                                  {'name': 'Thunderbolt Cable Speed Support',
                                                   'offset': 0,
                                                   'bit length': 3})

        TBTCableSpeedSupport.help = """Displays if a power mismatch has occurred."""
        TBTCableSpeedSupport.setReportList(['Reserved', 'USB3.1 gen1 cable (10Gb/s Thunderbolt support)', '10Gb/s only', '10Gb/s & 20Gb/s only'])
        TBTCableSpeedSupport.setMaxValue(3)
        self.addChild(TBTCableSpeedSupport)

        TBTCableGen = register_class.cListDMTerminator(self.register,
                                                  {'name': 'Thunderbolt Cable Gen',
                                                   'offset': 3,
                                                   'bit length': 2})

        TBTCableGen.help = """Displays if a power mismatch has occurred."""
        TBTCableGen.setReportList(['3rd generation TBT (10.3125 and 20.625 Gb/s)', '4th generation TBT (10.0, 10.3125, 20.0 and 20.625 Gb/s)'])
        TBTCableGen.setMaxValue(1)
        self.addChild(TBTCableGen)

        CableType = register_class.cListDMTerminator(self.register,
                                                  {'name': 'Cable Type',
                                                   'offset': 5,
                                                   'bit length': 1})

        CableType.help = """Status of the Thunderbolt Connection."""
        CableType.setReportList(['Type-C to Type-C Cable', 'Legacy Adapter'])
        self.addChild(CableType)

        activeCable = register_class.cListDMTerminator(self.register,
                                                  {'name': 'Active Cable',
                                                   'offset': 6,
                                                   'bit length': 1})

        CableType.help = """Status of the Thunderbolt Connection."""
        CableType.setReportList(['Active Cable', 'Passive Cable'])
        self.addChild(activeCable)

        ActiveLinkTraining = register_class.cListDMTerminator(self.register,
                                                  {'name': 'Active Link Training',
                                                   'offset': 7,
                                                   'bit length': 1})

        ActiveLinkTraining.help = """Status of Active Link Training connection."""
        ActiveLinkTraining.setReportList(['Active with bi-directional LSRX communication (also used for passive cables)', 'Active with uni-directional LSRX communication'])
        self.addChild(ActiveLinkTraining)


class cIntelVIDStatus_0x59_register(register_class.cRegister) :
    def __init__ (self):
        register_class.cRegister.__init__(self, {'register name' : 'Intel VID Status',
                                                 'address' : 0x59,
                                                 'byte length' : 11,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Intel VID Status',
                                                        'offset' : 0,
                                                        'bit length' : 88 })

        IntelVIDDetected = register_class.cHexDMTerminator(self,
                                                        {'name' : 'Intel VID Detected',
                                                        'offset' : 0,
                                                        'bit length' : 1 })
        IntelVIDDetected.help = """(DFP) UFP returned Intel VID in Discover SVIDs response or responded with ACK to Intel VID SVDM Commands\n\n(UFP) DFP has issued Intel VID SVDM (Discover Modes, Enter Mode, etc)"""
        self.dataModel.addChild(IntelVIDDetected)

        thunderboltModeActive = register_class.cHexDMTerminator(self,
                                                        {'name' : 'Thunderbolt Mode Active',
                                                        'offset' : 1,
                                                        'bit length' : 1 })
        thunderboltModeActive.help = """(DFP) PD Controller has entered Thunderbolt Mode with attached UFP\n\n(UFP) Attached DFP has entered Thunderbolt Mode """
        self.dataModel.addChild(thunderboltModeActive)

        errorCode = register_class.cHexDMTerminator(self,
                                                        {'name' : 'Error Code',
                                                        'offset' : 2,
                                                        'bit length' : 3 })
        errorCode.help = """Error Code"""
        self.dataModel.addChild(errorCode)

        TBTAttentionData = register_class.cHexDMTerminator(self,
                                                                {'name' : 'TBT Attention Data',
                                                                'offset' : 8,
                                                                'bit length' : 32 })
        TBTAttentionData.help = """Contents of Attention VDO in Thunderbolt Mode when sent (UFP) or received (DFP)"""
        self.dataModel.addChild(TBTAttentionData)

        TBTEnterModeData = cTBTEnterMode(self, 1,
                                                                {'name' : 'TBT Enter Mode Data',
                                                                'offset' : 40,
                                                                'bit length' : 16 })
        TBTEnterModeData.help = """Upper 16 bits of second VDO to Thunderbolt Enter Mode command when sent (DFP) or received (UFP)"""
        self.dataModel.addChild(TBTEnterModeData)

        TBTDiscoverModeDataSOP = cTBTSOPResponse(self, 1,
                                                                {'name' : 'TBT Discover Mode Data SOP',
                                                                'offset' : 56,
                                                                'bit length' : 16 })
        TBTDiscoverModeDataSOP.help = """Upper 16 bits of SOP Discover Modes response for TBT Mode when received (DFP) or sent (UFP). Lower 16 bits of the response are always 0x0001. \n\nNOTE: In the UFP role, this register simply copies the contents of the Intel VID Configuration register bits 23:8 at the time the Discover Modes response is generated."""
        self.dataModel.addChild(TBTDiscoverModeDataSOP)

        TBTDiscoverModeDataSOPP= cTBTSOPPrimeResponse(self, 1,
                                                                {'name' : 'TBT Discover Mode Data SOPP',
                                                                'offset' : 72,
                                                                'bit length' : 16 })
        TBTDiscoverModeDataSOPP.help = """Upper 16 bits of SOP' Discover Modes Cable response for TBT Mode. Lower 16 bits of the response are always 0x0001 """
        self.dataModel.addChild(TBTDiscoverModeDataSOPP)



class cDMUnstructuredVDO0(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)


        payload = register_class.cHexDMTerminator(self.register,
                                                            {'name' : 'Payload',
                                                             'offset' : 0,
                                                             'bit length' : 15 })

        self.addChild(payload)

        structType = register_class.cListDMTerminator(self.register,
                                                            {'name' : 'Type',
                                                             'offset' : 15,
                                                             'bit length' : 1 })
        structType.setReportList(['Unstructured',
                               'Structured'])

        self.addChild(structType)

        SVID = register_class.cHexDMTerminator(self.register,
                                                            {'name' : 'SVID',
                                                             'offset' : 16,
                                                             'bit length' : 16 })

        self.addChild(SVID)


class cDMStructuredVDO0(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)



        cmd = register_class.cListDMTerminator(self.register,
                                                            {'name' : 'Command',
                                                             'offset' : 0,
                                                             'bit length' : 5 })
        cmd.setReportList(['Reserved (0x0)',
                           'Discover Identity',
                           'Discover SVIDs',
                           'Discover Modes',
                           'Enter Mode',
                           'Exit Mode',
                           'Attention',
                           'Reserved (0x7)',
                           'Reserved (0x8)',
                           'Reserved (0x9)',
                           'Reserved (0xA)',
                           'Reserved (0xB)',
                           'Reserved (0xC)',
                           'Reserved (0xD)',
                           'Reserved (0xE)',
                           'Reserved (0xF)',
                           'Status Update',
                           'Config',
                           'Send Data Msg',
                           'Msg Received',
                           'Send PDIO Status',
                           'Rx PDIO Status',
                           'Reserved (0x16)',
                           'Reserved (0x17)',
                           'Reserved (0x18)',
                           'Reserved (0x19)',
                           'Reserved (0x1A)',
                           'Reserved (0x1B)',
                           'Cable Disconnect or Hard Reset',
                           'Early Enter Mode',
                           'Mode Etnered',
                           'Config Complete'])

        self.addChild(cmd)

        cmdType = register_class.cListDMTerminator(self.register,
                                                            {'name' : 'Command Type',
                                                             'offset' : 6,
                                                             'bit length' : 2 })
        cmdType.setReportList(['Initiator',
                           'Responder ACK',
                           'Responder NACK',
                           'Responder Busy'])

        self.addChild(cmdType)

        objPosn = register_class.cDecimalDMTerminator(self.register,
                                                            {'name' : 'Object Position',
                                                             'offset' : 8,
                                                             'bit length' : 3 })

        self.addChild(objPosn)

        vdmVers = register_class.cDecimalDMTerminator(self.register,
                                                            {'name' : 'VDM Version',
                                                             'offset' : 13,
                                                             'bit length' : 2 })
        self.addChild(vdmVers)

        structType = register_class.cListDMTerminator(self.register,
                                                            {'name' : 'Type',
                                                             'offset' : 15,
                                                             'bit length' : 1 })
        structType.setReportList(['Unstructured',
                               'Structured'])

        self.addChild(structType)

        SVID = register_class.cHexDMTerminator(self.register,
                                                            {'name' : 'SVID',
                                                             'offset' : 16,
                                                             'bit length' : 16 })

        self.addChild(SVID)


# differentiates between structured and unstructured VDO 0 and interprets accordingly
class cDMAnyFirstVDO(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        self.structuredOverlay = cDMStructuredVDO0(register, self.tier, iDict)
        self.unstructuredOverlay = cDMUnstructuredVDO0(register, self.tier, iDict)

        # self.dataModelChildrenArray must contain the children in all three of the overlays
        self.dataModelChildrenArray = []
        self.dataModelChildrenArray.extend(self.structuredOverlay.dataModelChildrenArray)
        self.dataModelChildrenArray.extend(self.unstructuredOverlay.dataModelChildrenArray)

        self.dataModelGenerator = self.AnyVdoArrayDMGenerator

    def hide(self) :
        self.structuredOverlay.hide()
        self.unstructuredOverlay.hide()

    def unhide(self) :
        self.structuredOverlay.unhide()
        self.unstructuredOverlay.unhide()

    def AnyVdoArrayDMGenerator(self):
        self.structuredOverlay.parent = self.parent
        self.unstructuredOverlay.parent = self.parent

        type = self.structuredOverlay.getChildByName('Type').valueToInt()

        if type == 0 :
            return self.unstructuredOverlay.childrenAsListDMGenerator()
        else :
            return self.structuredOverlay.childrenAsListDMGenerator()




# display pdos based on numPdo
# not a method, but should be grouped with txSrcCap class
def cRxAttention_TopLevelDMGenerator(self) :

    numVdo = self.getChildByName('RX Attention Status').getChildByName('Number of Valid VDOs').valueToInt()

    for i in range(7) :
        if i < numVdo :
            self.getChildByName('Data Objects Received').dataModelChildrenArray[i].unhide()
        else :
            self.getChildByName('Data Objects Received').dataModelChildrenArray[i].hide()

    if numVdo == 0 :
        self.getChildByName('Data Objects Received').hide()
    else :
        self.getChildByName('Data Objects Received').unhide()

    return self.childrenAsListDMGenerator()


class cRxAttention_0x4E_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'RX Attention structured VDM',
                                                 'address' : 0x4E,
                                                 'byte length' : 29,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'RX Attention structured Register',
                                                        'offset' : 0,
                                                        'bit length' : 232 })


        rxAttentionStatus = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'RX Attention Status',
                                                        'offset' : 0,
                                                        'bit length' : 232 })

        self.dataModel.addChild(rxAttentionStatus)


        rxVdmNumValid = register_class.cDecimalDMTerminator(self,
                                                            {'name' : 'Number of Valid VDOs',
                                                             'offset' : 0,
                                                             'bit length' : 3 })

        rxVdmNumValid.help = """The number of valid VDOs assigned to this PD Controller."""
        rxVdmNumValid.updateRegisters.append(self)
        rxAttentionStatus.addChild(rxVdmNumValid)

        rxVdmSequenceNum = register_class.cDecimalDMTerminator(self,
                                                            {'name' : 'Number of Register Updates',
                                                             'offset' : 5,
                                                             'bit length' : 3 })

        rxVdmSequenceNum.help = """Increments by one every time this register is updated, rolls over upon reflow."""
        rxVdmSequenceNum.updateRegisters.append(self)
        rxAttentionStatus.addChild(rxVdmSequenceNum)


        rxDataObjects = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Data Objects Received',
                                                        'offset' : 8,
                                                        'bit length' : 224 })

        self.dataModel.addChild(rxDataObjects)

        rxDataObjectOne = cDMAnyFirstVDO(self, 1,
                                                        {'name' : 'Data Object 1',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        rxDataObjects.addChild(rxDataObjectOne)

        for i in range(2,8) :
            dataObjX = register_class.cDataModelArray(self, 1,
                                                            {'name' : 'Data Object %d' %i,
                                                            'offset' : 32 * (i-1),
                                                            'bit length' : 32 })

            rxDataObjects.addChild(dataObjX)

            rxDataObjectX = register_class.cHexDMTerminator(self,
                                                                {'name' : 'Data Object %d' %i,
                                                                 'offset' : 0,
                                                                 'bit length' : 32 })

            rxDataObjectX.help = "Data Object %d of most recently received Attention SVDM." %i
            dataObjX.addChild(rxDataObjectX)

        self.dataModel.setDataModelGenerator(cRxAttention_TopLevelDMGenerator)


########################################################################################################################
########################################################################################################################
########################################################################################################################



# display pdos based on numPdo
# not a method, but should be grouped with txSrcCap class
def cRxVdm_TopLevelDMGenerator(self) :

    numVdo = self.getChildByName('RX VDM Status').getChildByName('Number of Valid VDOs').valueToInt()


    for i in range(7) :
        if i < numVdo :
            self.getChildByName('Data Objects Received').dataModelChildrenArray[i].unhide()
        else :
            self.getChildByName('Data Objects Received').dataModelChildrenArray[i].hide()


    if numVdo == 0 :
        self.getChildByName('Data Objects Received').hide()
    else :
        self.getChildByName('Data Objects Received').unhide()



    return self.childrenAsListDMGenerator()



class cRxVdm_0x4F_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'RX VDM Register',
                                                 'address' : 0x4F,
                                                 'byte length' : 29,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'RX VDM Register',
                                                        'offset' : 0,
                                                        'bit length' : 232 })


        rxVdmStatus = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'RX VDM Status',
                                                        'offset' : 0,
                                                        'bit length' : 232 })

        self.dataModel.addChild(rxVdmStatus)


        rxVdmNumValid = register_class.cDecimalDMTerminator(self,
                                                            {'name' : 'Number of Valid VDOs',
                                                             'offset' : 0,
                                                             'bit length' : 3 })
        rxVdmNumValid.help = """Number of valid Source VDOs that will be transmitted to the sink at the other end of the USB Type-C cable using USB-PD protocol. The PD Controller can transmit between 0 and 7 Source VDOs"""
        rxVdmNumValid.updateRegisters.append(self)

        rxVdmStatus.addChild(rxVdmNumValid)



        rxVdmSource = register_class.cListDMTerminator(self,
                                                    {'name' : 'SOP Message Source',
                                                     'offset' : 3,
                                                     'bit length' : 2 })

        rxVdmSource.setMaxValue(3)
        rxVdmSource.setReportList(['VDM came from SOP', 'VDM came from SOP*', 'VDM came from SOP**', 'VDM came from SOP*_Debug'])
        rxVdmSource.setFixedOffset(3)
        rxVdmSource.help = """SOP* of message source."""
        rxVdmSource.updateRegisters.append(self)

        rxVdmStatus.addChild(rxVdmSource)

        rxVdmSequenceNum = register_class.cDecimalDMTerminator(self,
                                                            {'name' : 'Number of Register Updates',
                                                             'offset' : 5,
                                                             'bit length' : 3 })

        rxVdmSequenceNum.updateRegisters.append(self)
        rxVdmSequenceNum.help = """Increments by one every time this register is updated, rolls over upon reflow."""
        rxVdmStatus.addChild(rxVdmSequenceNum)

        rxDataObjects = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Data Objects Received',
                                                        'offset' : 8,
                                                        'bit length' : 224 })

        self.dataModel.addChild(rxDataObjects)

        rxDataObjectOne = cDMAnyFirstVDO(self, 1,
                                                        {'name' : 'Data Object 1',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        rxDataObjects.addChild(rxDataObjectOne)

        for i in range(2,8) :
            dataObjX = register_class.cDataModelArray(self, 1,
                                                            {'name' : 'Data Object %d' %i,
                                                            'offset' : 32 * (i-1),
                                                            'bit length' : 32 })

            rxDataObjects.addChild(dataObjX)

            rxDataObjectX = register_class.cHexDMTerminator(self,
                                                                {'name' : 'Data Object %d' %i,
                                                                 'offset' : 0,
                                                                 'bit length' : 32 })

            rxDataObjectX.help = "Data Object %d of most recently received Attention SVDM." %i
            dataObjX.addChild(rxDataObjectX)


        self.dataModel.setDataModelGenerator(cRxVdm_TopLevelDMGenerator)



def GPIODMGenerator(self) :
    eventListNum = self.getChildByName('Mapped Event').valueToInt()
    eventDict = self.register.GPIOEventDictList[eventListNum]

    if eventListNum == -2 :
        inout = 'neither'
    elif eventListNum == -1 :
        inout = 'output'
    else :
        inout = eventDict['inout']

    if inout == 'output' :
        self.getChildByName('Output Enable').hide()
        self.getChildByName('Interrupt Enable').hide()
        self.getChildByName('Initial Value').unhide()
        self.getChildByName('Open Drain Output Enable').unhide()
        self.getChildByName('GPIO Output Level').unhide()
        self.getChildByName('Internal Pull Down Enable').unhide()
        self.getChildByName('Internal Pull Up Enable').unhide()
        self.getChildByName('Map Pin to GPIO or ADC').hide()
    elif inout == 'input' :
        self.getChildByName('Output Enable').hide()
        self.getChildByName('Interrupt Enable').hide()
        self.getChildByName('Initial Value').hide()
        self.getChildByName('Open Drain Output Enable').hide()
        self.getChildByName('GPIO Output Level').hide()
        self.getChildByName('Internal Pull Down Enable').unhide()
        self.getChildByName('Internal Pull Up Enable').unhide()
        self.getChildByName('Map Pin to GPIO or ADC').hide()
    else :
        self.getChildByName('Output Enable').hide()
        self.getChildByName('Interrupt Enable').hide()
        self.getChildByName('Initial Value').hide()
        self.getChildByName('Open Drain Output Enable').hide()
        self.getChildByName('GPIO Output Level').hide()
        self.getChildByName('Internal Pull Down Enable').hide()
        self.getChildByName('Internal Pull Up Enable').hide()
        self.getChildByName('Map Pin to GPIO or ADC').hide()

    return self.childrenAsListDMGenerator()


#  packed arguments:
# [0] event 0 gpio
# [1] event 0 enable
# [2] event 1 gpio
# [3] event 1 enable
# etc
def eventDerivedFxn(argumentList, gpioNum) :
    for i in range(len(argumentList) // 2) :
        if argumentList[(2*i)].valueToInt() == gpioNum :
            if argumentList[(2*i)+1].valueToInt() == 1 :
                return i

    return None

# packed arguments:
# [0] event 0 gpio
# [1] event 0 enable
# [2] event 1 gpio
# [3] event 1 enable
# etc
# packed return:
# [0] event 0 gpio
# [1] event 0 enable
# [2] event 1 gpio
# [3] event 1 enable
# etc
def eventUpdateFxn(value, argumentList, gpioNum) :
    # clear this gpioNum from table
    for i in range(len(argumentList) // 2) :
        if argumentList[(2*i)].valueToInt() == gpioNum :
            argumentList[(2*i)].setFromInt(0)
            argumentList[(2*i)+1].setFromInt(0)

    if value >= 0 :
        argumentList[(2*value)].setFromInt(gpioNum)
        argumentList[(2*value) +1].setFromInt(1)



def eventSetFromInt(self, listNum) :
    if self.register.GPIOEventDictList[listNum]['inout'] == 'output' :
        self.parent.getChildByName('Output Enable').setFromInt(1)
        self.parent.getChildByName('Interrupt Enable').setFromInt(0)
        self.parent.getChildByName('Map Pin to GPIO or ADC').setFromInt(0)
    elif self.register.GPIOEventDictList[listNum]['inout'] == 'input' :
        self.parent.getChildByName('Output Enable').setFromInt(0)
        self.parent.getChildByName('Interrupt Enable').setFromInt(1)
        self.parent.getChildByName('Initial Value').setFromInt(0)
        self.parent.getChildByName('Open Drain Output Enable').setFromInt(0)
        self.parent.getChildByName('GPIO Output Level').setFromInt(0)
        self.parent.getChildByName('Map Pin to GPIO or ADC').setFromInt(0)
    else :
        # neither
        self.parent.getChildByName('Output Enable').setFromInt(0)
        self.parent.getChildByName('Interrupt Enable').setFromInt(0)
        self.parent.getChildByName('Initial Value').setFromInt(0)
        self.parent.getChildByName('Open Drain Output Enable').setFromInt(0)
        self.parent.getChildByName('GPIO Output Level').setFromInt(0)
        self.parent.getChildByName('Internal Pull Down Enable').setFromInt(0)
        self.parent.getChildByName('Internal Pull Up Enable').setFromInt(0)
        self.parent.getChildByName('Map Pin to GPIO or ADC').setFromInt(1)

    if listNum == -1 :
        self.parent.getChildByName('Output Enable').setFromInt(1)
        self.parent.getChildByName('Interrupt Enable').setFromInt(0)
        self.parent.getChildByName('Map Pin to GPIO or ADC').setFromInt(0)

    if listNum == -2 :
        self.parent.getChildByName('Output Enable').setFromInt(0)
        self.parent.getChildByName('Interrupt Enable').setFromInt(0)
        self.parent.getChildByName('Initial Value').setFromInt(0)
        self.parent.getChildByName('Open Drain Output Enable').setFromInt(0)
        self.parent.getChildByName('GPIO Output Level').setFromInt(0)
        self.parent.getChildByName('Internal Pull Down Enable').setFromInt(0)
        self.parent.getChildByName('Internal Pull Up Enable').setFromInt(0)
        self.parent.getChildByName('Map Pin to GPIO or ADC').setFromInt(1)

    self.privateSetFromInt(listNum)

def eventValueToInt(self) :
    # find the match to our GPIO
    # if there is no match and GPIO is enabled, this is -1 mapped without event
    #    if there is no match and GPIO is disabled, this is -2
    # So initialize as such and then search for match

    eventFromSearch = self.privateValueToInt()

    if eventFromSearch == None :
        if self.parent.getChildByName('Output Enable').valueToInt() == 1 :
            eventNum = -1
        else :
            eventNum = -2
    else :
        eventNum = eventFromSearch

    return eventNum



#  This covers the flag offsets
#  Have to append event record since it uses different offset structure
class cGPIOFlagOffsets(register_class.cDataModelArray) :
    def __init__(self, register, tier, virtual, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        enable = register_class.cBooleanDMTerminator(self.register,
                                                      {'name' : 'Output Enable',
                                                        'offset' : 0,
                                                        'bit length' : 1 })

        self.addChild(enable)

        intEnable = register_class.cBooleanDMTerminator(self.register,
                                                      {'name' : 'Interrupt Enable',
                                                        'offset' : 32,
                                                        'bit length' : 1 })

        self.addChild(intEnable)

        initData = register_class.cDataModelTerminator(self.register,
                                                      {'name' : 'Initial Value',
                                                        'offset' : 64,
                                                        'bit length' : 1 })

        self.addChild(initData)

        openDrain = register_class.cBooleanDMTerminator(self.register,
                                                      {'name' : 'Open Drain Output Enable',
                                                        'offset' : 96,
                                                        'bit length' : 1 })

        self.addChild(openDrain)

        ldo3P3 = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'GPIO Output Level',
                                                        'offset' : 128,
                                                        'bit length' : 1 })

        ldo3P3.setReportList(['VDDIO', 'LDO3V3'])


        self.addChild(ldo3P3)

        intPullDown = register_class.cBooleanDMTerminator(self.register,
                                                      {'name' : 'Internal Pull Down Enable',
                                                        'offset' : 160,
                                                        'bit length' : 1 })

        self.addChild(intPullDown)

        intPullUp = register_class.cBooleanDMTerminator(self.register,
                                                      {'name' : 'Internal Pull Up Enable',
                                                        'offset' : 192,
                                                        'bit length' : 1 })

        self.addChild(intPullUp)

        hiZ = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'Map Pin to GPIO or ADC',
                                                        'offset' : 224,
                                                        'bit length' : 1 })

        hiZ.setReportList(['GPIO', 'ADC (Hi-Z)'])

        self.addChild(hiZ)

        if virtual == True :
            # we don't have a real offset, but use as index to find correct mapping
            event = register_class.cVirtualDictDMTerminator(self.register,
                                                          {'name' : 'Mapped Event',
                                                            'offset' : self.offset,
                                                            'bit length' : 8 })

            event.setReportDict(self.register.eventReportDict)
            event.setReplaceDict(self.register.eventReplaceDict)


            # Define mapping from virtual field to register fields
            event.setMethodSetFromInt(eventSetFromInt)
            event.setMethodValueToInt(eventValueToInt)

            eventPhysicalList = []

            for i in range(self.register.NumGPIOEvents) :
                if i < 32 :
                    eventPhysicalList.append(['GPIO Event Map', 'GPIO Event #%d -- %s' %(i, self.register.GPIOEventDictList[i]['name']), 'GPIO Number'])
                    eventPhysicalList.append(['GPIO Event Map', 'GPIO Event #%d -- %s' %(i, self.register.GPIOEventDictList[i]['name']), 'Event Enable'])
                else :
                    eventPhysicalList.append(['GPIO Event Map (0x5D)', 'GPIO Event #%d -- %s' %(i, self.register.GPIOEventDictList[i]['name']), 'GPIO Number'])
                    eventPhysicalList.append(['GPIO Event Map (0x5D)', 'GPIO Event #%d -- %s' %(i, self.register.GPIOEventDictList[i]['name']), 'Event Enable'])

            event.registerAsDerivedField(lambda argumentList, gpioNum = self.offset : eventDerivedFxn(argumentList, gpioNum),
                lambda argumentList, value, gpioNum = self.offset : eventUpdateFxn(argumentList, value, gpioNum), eventPhysicalList)


            event.setMaxValue(len(self.register.GPIOEventDictList)-1)
            event.setMinValue(-2)
            event.updateRegisters.append(self.register)

            self.addChild(event)

            self.setDataModelGenerator(GPIODMGenerator)



#  This covers the flag offsets
#  Have to append event record since it uses different offset structure
class cGPIOEventRecord(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        gpioList = []

        for i in range(self.register.NumMappableGPIO) :
            gpioList.append('GPIO %d' %i)


        gpioNum = register_class.cListDMTerminator(self.register,
                                                      {'name' : 'GPIO Number',
                                                        'offset' : 0,
                                                        'bit length' : 5 })

        gpioNum.setMaxValue(len(gpioList) -2)
        gpioNum.setReportList(gpioList)

        self.addChild(gpioNum)

        eventEnable = register_class.cBooleanDMTerminator(self.register,
                                                      {'name' : 'Event Enable',
                                                        'offset' : 7,
                                                        'bit length' : 1 })

        self.addChild(eventEnable)

GPIOEventDictList = [
    {'name' : 'Disabled', 'inout' : 'neither' },
    {'name' : 'Output Enabled Without Event', 'inout' : 'output' },
    {'name' : 'Plug Event', 'inout' : 'output' },
    {'name' : 'Port Connected CC2 (Cable Orientation Event)', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'Source (1) / Sink (0) / Unattached (High-Z) event', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'input' },
    {'name' : 'Fault Condition (Active Low) Event', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'Either DP or USB Event', 'inout' : 'output' },
    {'name' : 'DP Mode Selection Event', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'Supply P5V Event', 'inout' : 'output' },
    {'name' : 'Supply HV Event', 'inout' : 'output' },
    {'name' : 'Supply HVE Event', 'inout' : 'output' },
    {'name' : 'Supply PPCable Event', 'inout' : 'output' },
    {'name' : 'Attached (Active Low) Event', 'inout' : 'output' },
    {'name' : 'VBUS Detect Event', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'P5V Overcurrent Event', 'inout' : 'output' },
    {'name' : 'Sink (1) / Source (0) Event', 'inout' : 'output' },
    {'name' : 'USB3 Event', 'inout' : 'output' },
    {'name' : 'USB2 Event', 'inout' : 'output' },
    {'name' : '2-lane DP Event', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'AMSEL event', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'PP_EXT Switch Closed Event', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'Sink < Threshold Voltage Event', 'inout' : 'output' },
    {'name' : 'Sink = Threshold Voltage Event', 'inout' : 'output' },
    {'name' : 'Sink > Threshold Voltage Event', 'inout' : 'output' },
    {'name' : 'HS_SEL0 (DP Pin Assign ACE = 1, BDF=0)', 'inout' : 'output' },
    {'name' : 'UFP (0) / DFP (1) Event', 'inout' : 'output' },
    {'name' : 'DP or USB3 (Active Low) Event', 'inout' : 'output' },
    {'name' : 'AC Detect Event', 'inout' : 'output' },
    {'name' : 'Consumer No AC Event', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'Port Connected, CC1 Data Channel', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'reserved', 'inout' : 'neither' },
    {'name' : 'Barrel Jack Detect Event', 'inout' : 'input' },
    {'name' : 'PDIO (TI Alternate Mode) Input 0', 'inout' : 'input' },
    {'name' : 'PDIO (TI Alternate Mode) Input 1', 'inout' : 'input' },
    {'name' : 'PDIO (TI Alternate Mode) Input 2', 'inout' : 'input' },
    {'name' : 'PDIO (TI Alternate Mode) Input 3', 'inout' : 'input' },
    {'name' : 'PDIO (TI Alternate Mode) Output 0', 'inout' : 'output' },
    {'name' : 'PDIO (TI Alternate Mode) Output 1', 'inout' : 'output' },
    {'name' : 'PDIO (TI Alternate Mode) Output 2', 'inout' : 'output' },
    {'name' : 'PDIO (TI Alternate Mode) Output 3', 'inout' : 'output' },
    {'name' : 'Source PDO0 Negotiated ', 'inout' : 'output' },
    {'name' : 'Source PDO1 Negotiated ', 'inout' : 'output' },
    {'name' : 'Source PDO2 Negotiated ', 'inout' : 'output' },
    {'name' : 'Source PDO3 Negotiated ', 'inout' : 'output' },
    {'name' : 'Source PDOX Negotiated Truth Table LSB', 'inout' : 'output' },
    {'name' : 'Source PDOX Negotiated Truth Table Bit 2', 'inout' : 'output' },
    {'name' : 'Source PDOX Negotiated Truth Table MSB', 'inout' : 'output' },
    {'name' : 'VBUS UVP Quick Detect', 'inout' : 'output' },
    {'name' : 'reserved', 'inout' : 'input' },
    {'name' : 'reserved', 'inout' : 'output' },
    {'name' : 'Load App Config Set 1', 'inout' : 'input' },
    {'name' : 'Load App Config Set 2', 'inout' : 'input' },
    {'name' : 'Load App Config Set 3', 'inout' : 'input' },
    {'name' : 'USB EP Enable', 'inout' : 'input' },
    {'name' : 'HV or EXT Sink Event (Active high after Softstart)', 'inout' : 'output'},
    {'name' : 'PP_HV Active Event', 'inout' : 'output'},
    {'name' : 'PP_EXT Thermal Protection Active Low Event', 'inout' : 'output'},
    {'name' : 'PP_EXT Thermal Protection Active High Event', 'inout' : 'output'},
    {'name' : 'Present Billboard Event', 'inout' : 'output'},
]


def exerciseChildRecursive(DataModel) :
    if isinstance(DataModel, register_class.cDataModelArray) :
        for child in DataModel.dataModelChildrenArray :
            exerciseChildRecursive(child)
    else :
        DataModel.setFromInt(DataModel.valueToInt())


class cGPIOEventMap_0x5C_register(register_class.cRegister) :
    def __init__(self):
        self.NumMappableGPIO = 18

        # remove the first "no enabled event" event
        self.GPIOEventDictList = GPIOEventDictList[2:]

        # determine number of events before removing reserved
        self.NumGPIOEvents = len(self.GPIOEventDictList)

        register_class.cRegister.__init__(self, {'register name' : 'GPIO Event Map',
                                                 'address' : 0x5C,
                                                 'byte length' : 64,
                                                 'permission' : 'RW'})


        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'GPIO Event Map',
                                                        'offset' : 0,
                                                        'bit length' : 8 * (32 + self.NumGPIOEvents) })


        self.eventReportDict = {}
        self.eventReplaceDict = {}

        for (i, eventDict) in enumerate(GPIOEventDictList) :
            if GPIOEventDictList[i]['name'] != 'reserved' :
                self.eventReportDict[i-2] = GPIOEventDictList[i]['name']

        listGpioExclude = [4, 9, 10, 11]
        for i in range(self.NumMappableGPIO) :
            gpioFlags = cGPIOFlagOffsets(self, 1, True,
                                                        {'name' : 'Settings for GPIO #%d' %(i),
                                                        'offset' : i,
                                                        'bit length' : 480 })
            self.dataModel.addChild(gpioFlags)
            if i in listGpioExclude :
                gpioFlags.hide()


        for i in range(32) :

            gpioEvtX = cGPIOEventRecord(self, 1,
                                                              {'name' : 'GPIO Event #%d -- %s' %(i, self.GPIOEventDictList[i]['name']),
                                                               'offset' : 256 + (8*i),
                                                               'bit length' : 8 })

            self.dataModel.addChild(gpioEvtX)
            gpioEvtX.hide()

class cGPIOEventMap_0x5D_register(register_class.cRegister) :
    def __init__(self):
        self.NumMappableGPIO = 18

        # remove the first "no enabled event" event
        self.GPIOEventDictList = GPIOEventDictList[2:]

        # determine number of events before removing reserved
        self.NumGPIOEvents = len(self.GPIOEventDictList)

        register_class.cRegister.__init__(self, {'register name' : 'GPIO Event Map (0x5D)',
                                                 'address' : 0x5D,
                                                 'byte length' : 64,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'GPIO Event Map (0x5D)',
                                                        'offset' : 0,
                                                        'bit length' : 8 * (32 + self.NumGPIOEvents) })

        for i in range(self.NumGPIOEvents - 32) :

            gpioEvtX = cGPIOEventRecord(self, 1,
                                                              {'name' : 'GPIO Event #%d -- %s' %(i+32, self.GPIOEventDictList[i+32]['name']),
                                                               'offset' : 8*i,
                                                               'bit length' : 8 })

            self.dataModel.addChild(gpioEvtX)

        self.showRawOnly()

def intFrom4CC(value) :
    retVal = 0x0
    # little endian. First char takes position 0 of the array
    for (i,char) in enumerate(value) :
        retVal |= (ord(char) << (8*i))

    return retVal

cmdReportDict =  { intFrom4CC('!CMD') : '!CMD',
                   intFrom4CC('Gaid') : 'Gaid',
                   intFrom4CC('GAID') : 'GAID',
                   intFrom4CC('ANeg') : 'ANeg',
                   intFrom4CC('CRST') : 'CRST',
                   intFrom4CC('DBfg') : 'DBfg',
#                   intFrom4CC('FPWR') : 'FPWR',
#                   intFrom4CC('GPIO') : 'GPIO',
                   intFrom4CC('GPoe') : 'GPoe',
                   intFrom4CC('GPie') : 'GPie',
                   intFrom4CC('GPsh') : 'GPsh',
                   intFrom4CC('GPsl') : 'GPsl',
                   intFrom4CC('HRST') : 'HRST',
#                   intFrom4CC('LOCK') : 'LOCK',
#                   intFrom4CC('MEMr') : 'MEMr',
#                   intFrom4CC('MEMw') : 'MEMw',
#                   intFrom4CC('PDOf') : 'PDOf',
#                   intFrom4CC('PDTx') : 'PDTx',
                   intFrom4CC('SRDY') : 'SRDY',
                   intFrom4CC('SRYR') : 'SRYR',
#                   intFrom4CC('VDMs') : 'VDMs'
                }

cmdTaskReportDict = { intFrom4CC('!CMD') : '!CMD',
                  intFrom4CC('Gaid') : 'Gaid',
                  intFrom4CC('GAID') : 'GAID',
#                   intFrom4CC('ABRT') : 'ABRT',
                  intFrom4CC('AMDs') : 'AMDs',
                  intFrom4CC('AMDs') : 'AMEn',
                  intFrom4CC('AMEn') : 'AMEx',
                  intFrom4CC('AMEx') : 'ANeg',
#                  intFrom4CC('ASkE') : 'ASkE',
                  intFrom4CC('CRST') : 'CRST',
                  intFrom4CC('DBfg') : 'DBfg',
#                   intFrom4CC('FPWR') : 'FPWR',
                  intFrom4CC('GO2M') : 'GO2M',
#                   intFrom4CC('GPIO') : 'GPIO',
#                   intFrom4CC('GPMp') : 'GPMp',
                   intFrom4CC('GPoe') : 'GPoe',
                   intFrom4CC('GPie') : 'GPie',
                   intFrom4CC('GPsh') : 'GPsh',
                   intFrom4CC('GPsl') : 'GPsl',
                  intFrom4CC('GSkC') : 'GSkC',
                  intFrom4CC('GSrC') : 'GSrC',
                  intFrom4CC('HRST') : 'HRST',
#                  intFrom4CC('ISkE') : 'ISkE',
#                   intFrom4CC('LOCK') : 'LOCK',
#                   intFrom4CC('MDEr') : 'MDEr',
#                   intFrom4CC('MDEw') : 'MDEw',
#                   intFrom4CC('MEMr') : 'MEMr',
#                   intFrom4CC('MEMw') : 'MEMw',
#                   intFrom4CC('PDOf') : 'PDOf',
#                   intFrom4CC('PDTx') : 'PDTx',
                  intFrom4CC('SRDY') : 'SRDY',
                  intFrom4CC('SRYR') : 'SRYR',
                  intFrom4CC('SSrC') : 'SSrC',
                  intFrom4CC('SWDF') : 'SWDF',
                  intFrom4CC('SWSk') : 'SWSk',
                  intFrom4CC('SWSr') : 'SWSr',
                  intFrom4CC('SWUF') : 'SWUF',
                  intFrom4CC('SWVC') : 'SWVC',
#                   intFrom4CC('VDMs') : 'VDMs'
                      }


class cUserAMGpioCfgSet(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        AppCfgMaskLow = register_class.cHexDMTerminator(self.register,
                                        {'name' : 'App Config Mask, GPIO Low Transition or User AM Exit',
                                         'offset' : 0,
                                         'bit length' : 8 })

        self.addChild(AppCfgMaskLow)

        AppCfgMaskHigh = register_class.cHexDMTerminator(self.register,
                                        {'name' : 'App Config Mask, GPIO High Transition or User AM Enter',
                                         'offset' : 8,
                                         'bit length' : 8 })

        self.addChild(AppCfgMaskHigh)

        cmdOnlyChannel = register_class.cListDMTerminator(self.register,
                                        {'name' : 'Command Channel to use for Command (not Task) Slot',
                                         'offset' : 16,
                                         'bit length' : 2 })

        cmdOnlyChannel.setMaxValue(2)
        cmdOnlyChannel.setReportList(['CMD1 (0x08)', 'CMD2 (0x09)', 'CMD3 (0x1E)'])

        self.addChild(cmdOnlyChannel)


        reserved = register_class.cForceSetDMTerminator( self.register,  { 'name' : 'Reserved',
                                                                'offset' : 18,
                                                                'bit length' : 6,
                                                                'force value' : int(0),
                                                                'force display' : 'Reserved, Set 0' })

        self.addChild(reserved)
        reserved.setFromInt(0)
        reserved.hide()

        cmdTaskChannel = register_class.cListDMTerminator(self.register,
                                        {'name' : 'Command Channel to use for Command or Task Slot',
                                         'offset' : 24,
                                         'bit length' : 2 })

        cmdTaskChannel.setMaxValue(2)
        cmdTaskChannel.setReportList(['CMD1 (0x08)', 'CMD2 (0x09)', 'CMD3 (0x1E)'])

        self.addChild(cmdTaskChannel)

        reserved = register_class.cForceSetDMTerminator( self.register,  { 'name' : 'Reserved',
                                                                'offset' : 26,
                                                                'bit length' : 6,
                                                                'force value' : int(0),
                                                                'force display' : 'Reserved, Set 0' })

        self.addChild(reserved)
        reserved.setFromInt(0)
        reserved.hide()


        AMEntryGPIOHighCmd = register_class.cDictDMTerminator(self.register,
                                        {'name' : 'Alt Mode Entry / GPIO High 4CC Command (not Task)',
                                         'offset' : 32,
                                         'bit length' : 32 })

        AMEntryGPIOHighCmd.setReportDict(cmdReportDict)


        self.addChild(AMEntryGPIOHighCmd)


        AMEntryGPIOHighCmdTsk = register_class.cDictDMTerminator(self.register,
                                        {'name' : 'Alt Mode Entry / GPIO High 4CC Command or Task',
                                         'offset' : 64,
                                         'bit length' : 32 })

        AMEntryGPIOHighCmdTsk.setReportDict(cmdTaskReportDict)


        self.addChild(AMEntryGPIOHighCmdTsk)

        AMEntryGPIOLowCmd = register_class.cDictDMTerminator(self.register,
                                        {'name' : 'Alt Mode Exit / GPIO Low 4CC Command (not Task)',
                                         'offset' : 96,
                                         'bit length' : 32 })

        AMEntryGPIOLowCmd.setReportDict(cmdReportDict)


        self.addChild(AMEntryGPIOLowCmd)


        AMExitGPIOLowCmdTsk = register_class.cDictDMTerminator(self.register,
                                        {'name' : 'Alt Mode Exit / GPIO Low 4CC Command or Task',
                                         'offset' : 128,
                                         'bit length' : 32 })

        AMExitGPIOLowCmdTsk.setReportDict(cmdTaskReportDict)


        self.addChild(AMExitGPIOLowCmdTsk)




class cMiscellaneous_0x5E_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Miscellaneous Configuration',
                                                 'address' : 0x5E,
                                                 'byte length' : 64,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Miscellaneous Configuration',
                                                        'offset' : 0,
                                                        'bit length' : 512 })

        misc = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Miscellaneous Configuration',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        self.dataModel.addChild(misc)


        hpdGpio = register_class.cListDMTerminator(self,
                                                      {'name' : 'DP Hot Plug Detect GPIO',
                                                        'offset' : 3,
                                                        'bit length' : 2 })

        hpdGpio.setReportList(['GPIO 4 is HPD Transmit', 'GPIO 5 is HPD Transmit', 'GPIO 4 is HPD Transmit, GPIO 5 is Receive', 'GPIO 4 is HPD Transmit and Receive'])


        misc.addChild(hpdGpio)


        extRMReset = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'External Reset from MReset',
                                                        'offset' : 8,
                                                        'bit length' : 1 })

        misc.addChild(extRMReset)

        extRPolarity = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'External Reset Polarity',
                                                        'offset' : 9,
                                                        'bit length' : 1 })

        misc.addChild(extRPolarity)

        igCRCMis = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'Ignore Good CRC Mismatch',
                                                        'offset' : 17,
                                                        'bit length' : 1 })

        misc.addChild(igCRCMis)

        Lock3V3 = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'Lock 3V3 Output',
                                                        'offset' : 19,
                                                        'bit length' : 1 })

        misc.addChild(Lock3V3)

        I2C1Level3V3 = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'Use 3V3 for I2C1 Level',
                                                        'offset' : 20,
                                                        'bit length' : 1 })

        misc.addChild(I2C1Level3V3)

        I2C2Level3V3 = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'Use 3V3 for I2C2 Level',
                                                        'offset' : 21,
                                                        'bit length' : 1 })

        misc.addChild(I2C2Level3V3)

        for i in range(3) :
            appCfgGPIO = cUserAMGpioCfgSet(self, 1,
                                                            {'name' : 'App Config Group %d Settings' %(i+1),
                                                            'offset' : 32 + 160 * i,
                                                            'bit length' : 160 })

            self.dataModel.addChild(appCfgGPIO)


class cUserAMModeSettings(register_class.cDataModelArray) :
    def __init__(self, register, tier, iDict):
        register_class.cDataModelArray.__init__(self, register, tier, iDict)

        audEntryEnable = register_class.cBooleanDMTerminator(self.register,
                                                      {'name' : 'User VID Mode Autoentry Enabled',
                                                        'offset' : 0,
                                                        'bit length' : 1 })

        self.addChild(audEntryEnable)

        autoSendVdm = register_class.cBooleanDMTerminator(self.register,
                                        {'name' : 'Automatically Send VDM on Mode Entry',
                                         'offset' : 32,
                                         'bit length' : 1 })

        self.addChild(autoSendVdm)

        loadAppCfg = register_class.cBooleanDMTerminator(self.register,
                                        {'name' : 'Load App Config set On Mode Entry and Exit',
                                         'offset' : 64,
                                         'bit length' : 1 })

        self.addChild(loadAppCfg)




class cUserSvidConfig_0x4A_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'User Alternate Mode Config',
                                                 'address' : 0x4A,
                                                 'byte length' : 64,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'User Alternate Mode Config',
                                                        'offset' : 0,
                                                        'bit length' : 512 })

        enableFlags = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'General Settings',
                                                        'offset' : 0,
                                                        'bit length' : 24 })

        self.dataModel.addChild(enableFlags)



        vidEnable = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'User VID Enabled',
                                                        'offset' : 0,
                                                        'bit length' : 1 })

        enableFlags.addChild(vidEnable)

        uamVid = register_class.cHexDMTerminator(self,
                                                      {'name' : 'User Alternate Mode VID (Vendor ID)',
                                                        'offset' : 16,
                                                        'bit length' : 16 })

        enableFlags.addChild(uamVid)

        bbIndex = register_class.cHexDMTerminator(self,
                                                      {'name' : 'User Alternate Mode Billboard String Index',
                                                        'offset' : 8,
                                                        'bit length' : 8 })

        enableFlags.addChild(bbIndex)



        for i in range(4) :
            modeenable = register_class.cBooleanDMTerminator(self,
                                                          {'name' : 'User VID Mode %d Enabled' %(i+1),
                                                            'offset' : 32 + (i*8),
                                                            'bit length' : 1 })

            enableFlags.addChild(modeenable)

            userAmSettings = cUserAMModeSettings(self, 1,
                                        {'name' : 'User Alternate Mode #%d Settings' %(i+1),
                                         'offset' : 64 + (8*i),
                                         'bit length' : 416 })

            # we only have 3 app config sets, so hide app config checkbox for mode 4
            if i == 3 :
                userAmSettings.getChildByName('Load App Config set On Mode Entry and Exit').hide()

            modeNumber = register_class.cHexDMTerminator(self,
                                        {'name' : 'Mode Value',
                                         'offset' : 0,
                                         'bit length' : 32 })

            modeNumber.setFixedOffset(160 + (32 * i) )

            userAmSettings.prependChild(modeNumber)

            self.dataModel.addChild(userAmSettings)


        autoSendVdm = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Autosend VDM Data',
                                                        'offset' : 288,
                                                        'bit length' : 220 })

        self.dataModel.addChild(autoSendVdm)

        asVdoCount = register_class.cDecimalDMTerminator(self,
                                                      {'name' : 'Autosend VDM VDO Count',
                                                        'offset' : 208,
                                                        'bit length' : 3 })

        autoSendVdm.addChild(asVdoCount)

        for i in range(6) :
            asVdmData = register_class.cHexDMTerminator(self,
                                                          {'name' : 'Autosend VDM VDO %d Data' %(i+1),
                                                            'offset' : 32*i,
                                                            'bit length' : 32 })

            autoSendVdm.addChild(asVdmData)

        asVUseData = register_class.cHexDMTerminator(self,
                                                      {'name' : 'Autosend VDM Vendor Use Data',
                                                        'offset' : 192,
                                                        'bit length' : 16 })

        autoSendVdm.addChild(asVUseData)



########################################################################################################################
########################################################################################################################
########################################################################################################################

class cUserVidStatus_0x57_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'User VID Status Register',
                                                 'address' : 0x57,
                                                 'byte length' : 2,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'User VID Status',
                                                        'offset' : 0,
                                                        'bit length' : 16 })


        userVidStatus = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'User VID Status',
                                                        'offset' : 0,
                                                        'bit length' : 16 })

        self.dataModel.addChild(userVidStatus)


        vidDetected = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'User VID Detected',
                                                             'offset' : 0,
                                                             'bit length' : 1 })

        vidDetected.updateRegisters.append(self)

        vidDetected.help = """When this bit is set high the user VID has been detected"""

        userVidStatus.addChild(vidDetected)


        vidActive = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'User VID Active',
                                                             'offset' : 1,
                                                             'bit length' : 1 })

        vidActive.updateRegisters.append(self)

        vidActive.help = """When this bit is set high the user VID is active and at least one mode has been entered"""

        userVidStatus.addChild(vidActive)


        userVidErrorCode = register_class.cHexDMTerminator(self,
                                                            {'name' : 'User VID Error Code',
                                                             'offset' : 2,
                                                             'bit length' : 3 })

        userVidErrorCode.updateRegisters.append(self)

        userVidErrorCode.help = """User VID Error Code used for debugging purposes only."""

        userVidStatus.addChild(userVidErrorCode)



        userMode1Status = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'User VID Mode 1 Status',
                                                             'offset' : 9,
                                                             'bit length' : 1 })

        userMode1Status.updateRegisters.append(self)

        userMode1Status.help = """When this bit is set high it will indicate Mode 1 was entered for the user VID"""

        userVidStatus.addChild(userMode1Status)


        userMode2Status = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'User VID Mode 2 Status',
                                                             'offset' : 10,
                                                             'bit length' : 1 })

        userMode2Status.updateRegisters.append(self)

        userMode2Status.help = """When this bit is set high it will indicate Mode 2 was entered for the user VID"""

        userVidStatus.addChild(userMode2Status)


        userMode3Status = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'User VID Mode 3 Status',
                                                             'offset' : 11,
                                                             'bit length' : 1 })

        userMode3Status.updateRegisters.append(self)

        userMode3Status.help = """When this bit is set high it will indicate Mode 3 was entered for the user VID"""

        userVidStatus.addChild(userMode3Status)


        userMode4Status = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'User VID Mode 4 Status',
                                                             'offset' : 12,
                                                             'bit length' : 1 })

        userMode4Status.updateRegisters.append(self)

        userMode4Status.help = """When this bit is set high it will indicate Mode 4 was entered for the user VID"""

        userVidStatus.addChild(userMode4Status)

########################################################################################################################
########################################################################################################################
########################################################################################################################

class cTiVidStatus_0x5B_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'TI VID Status Register',
                                                 'address' : 0x5B,
                                                 'byte length' : 1,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'TI Mode Status',
                                                        'offset' : 0,
                                                        'bit length' : 8 })


        tividStatus1 = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Texas Instruments VID Status',
                                                        'offset' : 0,
                                                        'bit length' : 1 })

        self.dataModel.addChild(tividStatus1)


        tiVidStatus = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'TI VID Status',
                                                             'offset' : 0,
                                                             'bit length' : 1 })

        tiVidStatus.updateRegisters.append(self)

        tiVidStatus.help = """When this bit is set high the TI VID alternate mode has been entered."""

        tividStatus1.addChild(tiVidStatus)

        pdioStatus = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'TI PDIO Status',
                                                             'offset' : 1,
                                                             'bit length' : 1 })

        pdioStatus.updateRegisters.append(self)

        pdioStatus.help = """When this bit is set high the TI PDIO alternate mode has been entered."""

        tividStatus1.addChild(pdioStatus)


        tiVidErrorCode = register_class.cHexDMTerminator(self,
                                                            {'name' : 'TI VID Error Code',
                                                             'offset' : 2,
                                                             'bit length' : 3 })

        tiVidErrorCode.updateRegisters.append(self)

        tiVidErrorCode.help = """Texas Instruments VID Error Code used for debugging purposes only."""

        tividStatus1.addChild(tiVidErrorCode)

########################################################################################################################
########################################################################################################################
########################################################################################################################

# display pdos based on numPdo
# not a method, but should be grouped with txSrcCap class
def TxIDO_TopLevelDMGenerator(self) :

    numUfpIDO = self.getChildByName('Record Counts').getChildByName('Number of UFP Identity Objects').valueToInt()


    for i in range(6) :
        if i < numUfpIDO :
            self.getChildByName('UFP Discover Identity Response').dataModelChildrenArray[i].unhide()
        else :
            self.getChildByName('UFP Discover Identity Response').dataModelChildrenArray[i].hide()

    if numUfpIDO > 0 :
        self.getChildByName('UFP Discover Identity Response').unhide()
    else :
        self.getChildByName('UFP Discover Identity Response').hide()


    numTPIDO = self.getChildByName('Record Counts').getChildByName("Number of SOP' (Tethered Plug) Identity Objects").valueToInt()

    for i in range(6) :
        if i < numTPIDO :
            self.getChildByName("SOP' (Tethered Plug) Discover Identity Response").dataModelChildrenArray[i].unhide()
        else :
            self.getChildByName("SOP' (Tethered Plug) Discover Identity Response").dataModelChildrenArray[i].hide()

    if numTPIDO > 0 :
        self.getChildByName("SOP' (Tethered Plug) Discover Identity Response").unhide()
    else :
        self.getChildByName("SOP' (Tethered Plug) Discover Identity Response").hide()

    return self.childrenAsListDMGenerator()

########################################################################################################################
########################################################################################################################
########################################################################################################################

class cTxIDO_0x47_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Transmit Identity Data Object',
                                                 'address' : 0x47,
                                                 'byte length' : 49,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Transmit Identity Data Object',
                                                        'offset' : 0,
                                                        'bit length' : 392 })

        numIdoConfig = register_class.cDataModelArray(self, 1,
                                                      {'name' : 'Record Counts',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        self.dataModel.addChild(numIdoConfig)

        numUfpIDO = register_class.cDecimalDMTerminator(self,
                                                        {'name' : 'Number of UFP Identity Objects',
                                                         'offset' : 0,
                                                         'bit length' : 3 })
        numUfpIDO.help = """Select the number of upstream facing port identity objects to assign to this PD Controller."""
        numUfpIDO.setMaxValue(6)
        numUfpIDO.updateRegisters.append(self)
        numIdoConfig.addChild(numUfpIDO)
        # for now just allow the predefined IDO fields

        numTPIDO = register_class.cDecimalDMTerminator(self,
                                                       {'name' : "Number of SOP' (Tethered Plug) Identity Objects",
                                                        'offset' : 4,
                                                        'bit length' : 3 })
        numTPIDO.setMaxValue(6)
        numTPIDO.updateRegisters.append(self)
        numIdoConfig.addChild(numTPIDO)

        ufpIDO = register_class.cDataModelArray(self, 2,
                                                {'name' : 'UFP Discover Identity Response',
                                                 'offset' : 8,
                                                 'bit length' : 128 })


        self.dataModel.addChild(ufpIDO)
        ufpIDO.addChild(cUFPIDHeaderVDO(self, 1,
                                        {'name' : 'UFP IDO Header',
                                         'offset' : 0,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : 'Certification Test ID',
                                         'offset' : 32,
                                         'bit length' : 20 }))

        ufpIDO.addChild(cUFPProductVDO(self, 1,
                                        {'name' : 'Product Vendor Defined Object',
                                         'offset' : 64,
                                         'bit length' : 32 }))

        ufpIDO.addChild(cAMAVDO(self, 1,
                                        {'name' : 'Alternate Mode Adapter VDO',
                                         'offset' : 96,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : 'UFP IDO VDO #5',
                                         'offset' : 128,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : 'UFP IDO VDO #6',
                                         'offset' : 160,
                                         'bit length' : 32 }))


        ufpIDO = register_class.cDataModelArray(self, 2,
                                                {'name' : "SOP' (Tethered Plug) Discover Identity Response",
                                                 'offset' : 200,
                                                 'bit length' : 128 })


        self.dataModel.addChild(ufpIDO)
        ufpIDO.addChild(cUFPIDHeaderVDO(self, 1,
                                        {'name' : "SOP' (Tethered Plug) IDO Header",
                                         'offset' : 0,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : 'Certification Test ID',
                                         'offset' : 32,
                                         'bit length' : 20 }))

        ufpIDO.addChild(cUFPProductVDO(self, 1,
                                        {'name' : 'Product Vendor Defined Object',
                                         'offset' : 64,
                                         'bit length' : 32 }))

        ufpIDO.addChild(cCableVDO(self, 1,
                                        {'name' : 'Cable Vendor Defined Object',
                                         'offset' : 96,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : "SOP' (Tethered Plug) IDO VDO #5",
                                         'offset' : 128,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : "SOP' (Tethered Plug) IDO VDO #6",
                                         'offset' : 160,
                                         'bit length' : 32 }))



        self.dataModel.setDataModelGenerator(TxIDO_TopLevelDMGenerator)


########################################################################################################################
########################################################################################################################
########################################################################################################################

# display pdos based on numPdo
# not a method, but should be grouped with txSrcCap class
def RxIDO_SOP_TopLevelDMGenerator(self) :
    numUfpIDO = self.getChildByName('Record Counts').getChildByName('Number of Received Identity Objects').valueToInt()

    for i in range(6) :
        if i < numUfpIDO :
            self.getChildByName('Received SOP Identity Response').dataModelChildrenArray[i].unhide()
        else :
            self.getChildByName('Received SOP Identity Response').dataModelChildrenArray[i].hide()

    if numUfpIDO > 0 :
        self.getChildByName('Received SOP Identity Response').unhide()
    else :
        self.getChildByName('Received SOP Identity Response').hide()

    return self.childrenAsListDMGenerator()




class cRxIDO_SOP_0x48_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Received SOP Identity Data Object',
                                                 'address' : 0x48,
                                                 'byte length' : 25,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Received SOP Identity Data Object',
                                                        'offset' : 0,
                                                        'bit length' : 200 })

        numIdoConfig = register_class.cDataModelArray(self, 1,
                                                      {'name' : 'Record Counts',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        self.dataModel.addChild(numIdoConfig)

        numUfpIDO = register_class.cDecimalDMTerminator(self,
                                                        {'name' : 'Number of Received Identity Objects',
                                                         'offset' : 0,
                                                         'bit length' : 3 })
        numUfpIDO.setMaxValue(6)
        numUfpIDO.updateRegisters.append(self)
        numIdoConfig.addChild(numUfpIDO)
        # for now just allow the predefined IDO fields

        ufpIDO = register_class.cDataModelArray(self, 2,
                                                {'name' : 'Received SOP Identity Response',
                                                 'offset' : 8,
                                                 'bit length' : 192 })


        self.dataModel.addChild(ufpIDO)
        ufpIDO.addChild(cUFPIDHeaderVDO(self, 1,
                                        {'name' : 'UFP IDO Header',
                                         'offset' : 0,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : 'Certification Test ID',
                                         'offset' : 32,
                                         'bit length' : 20 }))

        ufpIDO.addChild(cUFPProductVDO(self, 1,
                                        {'name' : 'Product Vendor Defined Object',
                                         'offset' : 64,
                                         'bit length' : 32 }))

        ufpIDO.addChild(cAMAVDO(self, 1,
                                        {'name' : 'Alternate Mode Adapter VDO',
                                         'offset' : 96,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : 'UFP IDO VDO #5',
                                         'offset' : 128,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : 'UFP IDO VDO #6',
                                         'offset' : 160,
                                         'bit length' : 32 }))


        self.dataModel.setDataModelGenerator(RxIDO_SOP_TopLevelDMGenerator)


########################################################################################################################
########################################################################################################################
########################################################################################################################


# display pdos based on numPdo
# not a method, but should be grouped with txSrcCap class
def RxIDO_SOPPrime_TopLevelDMGenerator(self) :
    numTPIDO = self.getChildByName('Record Counts').getChildByName("Number of Received Identity Objects").valueToInt()

    if numTPIDO > 0 :
        self.getChildByName("Received SOP Prime Discover Identity Response").unhide()
    else :
        self.getChildByName("Received SOP Prime Discover Identity Response").hide()

    return self.childrenAsListDMGenerator()


class cRxIDO_SOPPrime_0x49_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Received SOP Prime Identity Data Object',
                                                 'address' : 0x49,
                                                 'byte length' : 25,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Received SOP Prime Identity Data Object',
                                                        'offset' : 0,
                                                        'bit length' : 200 })

        numIdoConfig = register_class.cDataModelArray(self, 1,
                                                      {'name' : 'Record Counts',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        self.dataModel.addChild(numIdoConfig)

        numUfpIDO = register_class.cDecimalDMTerminator(self,
                                                        {'name' : 'Number of Received Identity Objects',
                                                         'offset' : 0,
                                                         'bit length' : 3 })
        numUfpIDO.setMaxValue(6)
        numUfpIDO.updateRegisters.append(self)
        numIdoConfig.addChild(numUfpIDO)
        # for now just allow the predefined IDO fields

        ufpIDO = register_class.cDataModelArray(self, 2,
                                                {'name' : "Received SOP Prime Discover Identity Response",
                                                 'offset' : 200,
                                                 'bit length' : 128 })


        self.dataModel.addChild(ufpIDO)
        ufpIDO.addChild(cUFPIDHeaderVDO(self, 1,
                                        {'name' : "SOP Prime IDO Header",
                                         'offset' : 0,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : 'Certification Test ID',
                                         'offset' : 32,
                                         'bit length' : 20 }))

        ufpIDO.addChild(cUFPProductVDO(self, 1,
                                        {'name' : 'Product Vendor Defined Object',
                                         'offset' : 64,
                                         'bit length' : 32 }))

        ufpIDO.addChild(cCableVDO(self, 1,
                                        {'name' : 'Cable Vendor Defined Object',
                                         'offset' : 96,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : "SOP Prime IDO VDO #5",
                                         'offset' : 128,
                                         'bit length' : 32 }))

        ufpIDO.addChild(register_class.cHexDMTerminator(self,
                                        {'name' : "SOP Prime IDO VDO #6",
                                         'offset' : 160,
                                         'bit length' : 32 }))



        self.dataModel.setDataModelGenerator(RxIDO_SOPPrime_TopLevelDMGenerator)



class cDataControl_0x50_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Data Control Register',
                                                 'address' : 0x50,
                                                 'byte length' : 4,
                                                 'permission' : 'DRW'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Data Control Register',
                                                        'offset' : 0,
                                                        'bit length' : 32 })


        dataControl = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Thunderbolt Data Control Register',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        self.dataModel.addChild(dataControl)

        hostConnected = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'Thunderbolt Host Connected',
                                                             'offset' : 0,
                                                             'bit length' : 1 })

        hostConnected.updateRegisters.append(self)

        hostConnected.help = """Indicates whether a Thunderbolt host is connected. Thunderbolt controller will force a Soft Reset when writing 1 to 0 and will cause a disconnect/reconnect"""

        dataControl.addChild(hostConnected)


        softReset = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'Soft Reset PD Controller',
                                                             'offset' : 1,
                                                             'bit length' : 1 })

        softReset.updateRegisters.append(self)

        softReset.help = """When this bit is set it will cause a Soft Reset of the PD controller, which is equivalent to the Gaid 4CC command"""

        dataControl.addChild(softReset)

        interruptAck = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'Interrupt Acknowledge',
                                                             'offset' : 2,
                                                             'bit length' : 1 })

        interruptAck.updateRegisters.append(self)

        interruptAck.help = """Thunderbolt controller will set this bit and all interrupts configured in IntMask are written to IntClear, clearing all interrupt events"""

        dataControl.addChild(interruptAck)


        StatusNak = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'Interrupt Acknowledge',
                                                             'offset' : 3,
                                                             'bit length' : 1 })

        StatusNak.updateRegisters.append(self)

        StatusNak.help = """(Host may write 0 or 1, no action to be taken)."""

        dataControl.addChild(StatusNak)




        usbHostConnected = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'USB Host Connected ',
                                                             'offset' : 4,
                                                             'bit length' : 1 })

        usbHostConnected.updateRegisters.append(self)

        usbHostConnected.help = """This bit is only applicable to Thunderbolt devices and indicates if there is a USB host connected upstream"""

        dataControl.addChild(usbHostConnected)


        dpHostConnected = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'DisplayPort Host Connected ',
                                                             'offset' : 5,
                                                             'bit length' : 1 })

        dpHostConnected.updateRegisters.append(self)

        dpHostConnected.help = """This bit is only applicable to Thunderbolt devices and indicates if there is a DisplayPort host (DFP_D) connected upstream"""

        dataControl.addChild(dpHostConnected)


        irq_Ack = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'Interrupt Present',
                                                             'offset' : 13,
                                                             'bit length' : 1 })

        irq_Ack.updateRegisters.append(self)

        irq_Ack.help = """This bit is will indicate is an interrupt has occured"""

        dataControl.addChild(irq_Ack)


        hpd_IrqSticky = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'DisplayPort HPD IRQ Present',
                                                             'offset' : 14,
                                                             'bit length' : 1 })

        hpd_IrqSticky.updateRegisters.append(self)

        hpd_IrqSticky.help = """This bit is only applicable to Thunderbolt devices and indicates if an DisplayPort Hot Plug Detect Interrupt was received from the DisplayPort sink (UFP_D)"""

        dataControl.addChild(hpd_IrqSticky)

        hpdLevel = register_class.cBooleanDMTerminator(self,
                                                            {'name' : 'DisplayPort HPD High/Low',
                                                             'offset' : 15,
                                                             'bit length' : 1 })

        hpdLevel.updateRegisters.append(self)

        hpdLevel.help = """This bit is only applicable to Thunderbolt devices and indicates the DisplayPort Hot Plug Detect High/Low level from the DisplayPort sink (UFP_D)"""

        dataControl.addChild(hpdLevel)



class cDisplayPortCapabilities_0x51_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Display Port Capabilities',
                                                 'address' : 0x51,
                                                 'byte length' : 7,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Display Port Capabilities',
                                                        'offset' : 0,
                                                        'bit length' : 56 })


        enDPSid = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Enable Display Port SID',
                                                         'offset' : 0,
                                                         'bit length' : 1 })
        self.dataModel.addChild(enDPSid)

        enDPMode = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Enable Display Port Mode 1',
                                                         'offset' : 1,
                                                         'bit length' : 1 })
        self.dataModel.addChild(enDPMode)

        portCap = register_class.cListDMTerminator(self,
                                                        {'name' : 'Port Capability',
                                                         'offset' : 8,
                                                         'bit length' : 2 })

        portCap.setReportList(['DP Disabled', 'DP UFP_D only', 'DP DFP_D only', 'DP UFP_D and DFP_D'])

        self.dataModel.addChild(portCap)

        signalling = register_class.cListDMTerminator(self,
                                                        {'name' : 'DisplayPort Signalling',
                                                         'offset' : 10,
                                                         'bit length' : 4 })

        signalling.setMaxValue(2)

        signalling.setReportList(['unspecified', 'DP 1.3', 'USB Gen 2.0'])

        self.dataModel.addChild(signalling)

        receptIndic = register_class.cListDMTerminator(self,
                                                        {'name' : 'Receptacle Indication',
                                                         'offset' : 14,
                                                         'bit length' : 1 })

        receptIndic.setReportList(['Plug', 'Receptacle'])


        self.dataModel.addChild(receptIndic)

        usb2SNU = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'USB2.0 Signalling Not Used',
                                                         'offset' : 15,
                                                         'bit length' : 1 })
        self.dataModel.addChild(usb2SNU)


        dfpdpins = register_class.cMultiBooleanDMTerminator(self,
                                                        {'name' : 'DFPD Receptacle or UFPD Plug Pin Assignment',
                                                         'offset' : 16,
                                                         'bit length' : 8 })
        dfpdpins.setFlagNameList(['A', 'B', 'C', 'D', 'E', 'F'])
        dfpdpins.setFlagMask([1, 1, 1, 1, 1, 1, 0, 0])
        dfpdpins.setSpacing(6)
        self.dataModel.addChild(dfpdpins)

        ufpdpins = register_class.cMultiBooleanDMTerminator(self,
                                                        {'name' : 'UFPD Receptacle or DFPD Plug Pin Assignment',
                                                         'offset' : 24,
                                                         'bit length' : 8 })

        ufpdpins.setFlagNameList(['A', 'B', 'C', 'D', 'E', 'F'])
        ufpdpins.setFlagMask([1, 1, 1, 1, 1, 0, 0, 0])
        ufpdpins.setSpacing(6)
        self.dataModel.addChild(ufpdpins)

        multiFunc = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Multifunction Preferred',
                                                         'offset' : 32,
                                                         'bit length' : 1 })
        self.dataModel.addChild(multiFunc)


        muxSwap = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Mux Swap',
                                                         'offset' : 33,
                                                         'bit length' : 1 })
        self.dataModel.addChild(muxSwap)

        multiFunc = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'DisplayPort Mode Auto Entry Allowed',
                                                         'offset' : 41,
                                                         'bit length' : 1 })
        self.dataModel.addChild(multiFunc)

        string_list = ['No Custom Vendor ID 4 Billboard String',]
        for i in range(1,16) :
            string_list.append('Custom Vendor ID 4 Billboard String at Index %d' %i)

        billboardIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Billboard Index',
                                                                     'offset' : 48,
                                                                     'bit length' : 4 })

        billboardIndex.setReportList(string_list)

        billboardIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Billboard Index',
                                                                'offset' : 48,
                                                                'bit length' : 8,
                                                                'force value' : int(6),
                                                                'force display' : '6',
                                                                'display widget' : billboardIndex })

        self.dataModel.addChild(billboardIndexFixed)
        billboardIndexFixed.setFromInt(6)

class cIntVidConf_0x52_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Intel VID Config Register',
                                                 'address' : 0x52,
                                                 'byte length' : 8,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Intel VID Config Register',
                                                        'offset' : 0,
                                                        'bit length' : 64 })


        vidConfig = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Intel VID Config Set',
                                                        'offset' : 0,
                                                        'bit length' : 16 })

        self.dataModel.addChild(vidConfig)

        enIntVid = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Enable Intel VID',
                                                         'offset' : 0,
                                                         'bit length' : 1 })
        enIntVid.help = """When this bit is set to 1, Intel VID is enabled. At least one mode from bit[71] must also be enabled for Intel VID to be enabled.When this bit is set to 0, Intel VID is disabled"""
        vidConfig.addChild(enIntVid)


        enIntMode = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Enable Intel Thunderbolt Mode',
                                                         'offset' : 1,
                                                         'bit length' : 1 })
        enIntMode.help = """When this bit is set to 1, ThunderboltTM Mode is enabled. #IntelVIDEnabled must also be enabled in bit[0] for this bit to enable ThunderBoltTM."""
        vidConfig.addChild(enIntMode)

        vout3V3R = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Thunderbolt Vout 3V3 Required',
                                                         'offset' : 8,
                                                         'bit length' : 1 })
        vout3V3R.help = """Always enable for Thunderbolt systems."""
        vidConfig.addChild(vout3V3R)

        emarkOverride = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Thunderbolt Emarker Override',
                                                         'offset' : 9,
                                                         'bit length' : 1 })
        emarkOverride.help = """Enabling will allow the PD Controller to enter Thunderbolt Alternate Mode without an E-Marked cable."""
        vidConfig.addChild(emarkOverride)

        anMinPowerReq = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'AN Minimum Power Required',
                                                         'offset' : 10,
                                                         'bit length' : 1 })
        anMinPowerReq.help = """With this enabled, the PD Controller will auto-negotiate the minimum power required for this mode."""
        vidConfig.addChild(anMinPowerReq)

        adaptResponse = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Adapter Mode Response',
                                                        'offset' : 16,
                                                        'bit length' : 16 })

        self.dataModel.addChild(adaptResponse)


        legacyTBTAdapter = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Legacy TBT Adapter',
                                                         'offset' : 0,
                                                         'bit length' : 1 })
        adaptResponse.addChild(legacyTBTAdapter)

        cableResponse = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Cable Mode Response',
                                                        'offset' : 32,
                                                        'bit length' : 16 })

        self.dataModel.addChild(cableResponse)


        cableSpeed = register_class.cDataModelTerminator(self,
                                                        {'name' : 'Cable Speed',
                                                         'offset' : 0,
                                                         'bit length' : 3 })
        cableResponse.addChild(cableSpeed)

        cableGen = register_class.cDataModelTerminator(self,
                                                        {'name' : 'Cable Generation',
                                                         'offset' : 3,
                                                         'bit length' : 2 })
        cableResponse.addChild(cableGen)

        cableType = register_class.cDataModelTerminator(self,
                                                        {'name' : 'Cable Type',
                                                         'offset' : 5,
                                                         'bit length' : 1 })
        cableResponse.addChild(cableType)

        cableActive = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Active Cable',
                                                         'offset' : 6,
                                                         'bit length' : 1 })
        cableResponse.addChild(cableActive)

        cableTraining = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Cable Training Supported',
                                                         'offset' : 7,
                                                         'bit length' : 1 })
        cableResponse.addChild(cableTraining)

        tbtAutoentry = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Thunderbolt Mode Autoentry Allowed',
                                                         'offset' : 49,
                                                         'bit length' : 1 })
        vidConfig.addChild(tbtAutoentry)

        string_list = ['No Custom Vendor ID 4 Billboard String',]
        for i in range(1,16) :
            string_list.append('Custom Vendor ID 4 Billboard String at Index %d' %i)

        billboardIndex = register_class.cListDMTerminator(self,
                                                                    {'name' : 'Billboard Index',
                                                                     'offset' : 48,
                                                                     'bit length' : 4 })

        billboardIndex.setReportList(string_list)

        billboardIndexFixed = register_class.cForceSetDMTerminator( self,  { 'name' : 'Billboard Index',
                                                                'offset' : 56,
                                                                'bit length' : 8,
                                                                'force value' : int(5),
                                                                'force display' : '5',
                                                                'display widget' : billboardIndex })

        self.dataModel.addChild(billboardIndexFixed)
        billboardIndexFixed.setFromInt(5)

class cTIVidConf_0x54_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Texas Instruments VID Config',
                                                 'address' : 0x54,
                                                 'byte length' : 12,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Texas Instruments VID Config',
                                                        'offset' : 0,
                                                        'bit length' : 96 })

        enTIVid = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Enable Texas Instruments VID',
                                                         'offset' : 0,
                                                         'bit length' : 1 })
        self.dataModel.addChild(enTIVid)

        enPDIOMode = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Enable PDIO Mode',
                                                         'offset' : 1,
                                                         'bit length' : 1 })
        self.dataModel.addChild(enPDIOMode)


#        enQuickswapMode = register_class.cBooleanDMTerminator(self,
#                                                        {'name' : 'Enable Quickswap Mode',
#                                                         'offset' : 2,
#                                                         'bit length' : 1 })
#        self.dataModel.addChild(enQuickswapMode)

        enPDIOAutoentry = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Enable PDIO Mode Autoentry',
                                                         'offset' : 9,
                                                         'bit length' : 1 })
        self.dataModel.addChild(enPDIOAutoentry)


#        enQuickswapAutoentry = register_class.cBooleanDMTerminator(self,
#                                                        {'name' : 'Enable Quickswap Mode Autoentry',
#                                                         'offset' : 10,
#                                                         'bit length' : 1 })
#        self.dataModel.addChild(enQuickswapAutoentry)

        messageIndex = register_class.cDataModelTerminator(self,
                                                        {'name' : 'Message Index',
                                                         'offset' : 16,
                                                         'bit length' : 8 })
        self.dataModel.addChild(messageIndex)

        pdioSignature = register_class.cDataModelTerminator(self,
                                                        {'name' : 'PDIO Signature',
                                                         'offset' : 32,
                                                         'bit length' : 32 })
        self.dataModel.addChild(pdioSignature)

#        quickswapSignature = register_class.cDataModelTerminator(self,
#                                                        {'name' : 'Quickswap Signature',
#                                                         'offset' : 64,
#                                                         'bit length' : 32 })
#        self.dataModel.addChild(quickswapSignature)



class cDataStatus_0x5F_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Data Status',
                                                 'address' : 0x5F,
                                                 'byte length' : 4,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Data Status',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        DataConnection = register_class.cListDMTerminator(self,
                                                  {'name': 'Data Connection',
                                                   'offset': 0,
                                                   'bit length': 1})

        DataConnection.help = """Highlights the Data Connection present on the device"""
        DataConnection.setReportList(['No data connection (rest of bits in this register are cleared)', 'Data connection present (at least one other bit in this register is nonzero)'])
        self.dataModel.addChild(DataConnection)

        DataOrientation = register_class.cListDMTerminator(self,
                                                  {'name': 'Data Orientation',
                                                   'offset': 1,
                                                   'bit length': 1})

        DataOrientation.help = """Highlights the Data Orientation present on the device"""
        DataOrientation.setReportList(['Plug is oriented on CC1 (upside-up) or no data connection', 'Plug is oriented on CC2 (upside-down) with a valid data connection.'])
        self.dataModel.addChild(DataOrientation)

        CableActive = register_class.cListDMTerminator(self,
                                                  {'name': 'Cable Active Orientation',
                                                   'offset': 2,
                                                   'bit length': 1})

        CableActive.help = """Determines if an active cable is attached."""
        CableActive.setReportList(['Cable is passive', 'Cable is active'])
        self.dataModel.addChild(CableActive)

        OverCurrentOrTemperature = register_class.cListDMTerminator(self,
                                                  {'name': 'Over Current Or Temperature',
                                                   'offset': 3,
                                                   'bit length': 1})

        OverCurrentOrTemperature.help = """Highlights if an Over Current Or Temperature has occurred."""
        OverCurrentOrTemperature.setReportList(['No over-current or over-temperature condition', 'Over-current or over-temperature condition has occurred.'])
        self.dataModel.addChild(OverCurrentOrTemperature)

        USB2Connection = register_class.cListDMTerminator(self,
                                                  {'name': 'USB2 Connection',
                                                   'offset': 4,
                                                   'bit length': 1})

        USB2Connection.help = """Highlights if a USB2.0 Connection is present."""
        USB2Connection.setReportList(['No USB2 connection to USB_RP', 'USB2 connection to USB_RP on Mission D+/D- pair'])
        self.dataModel.addChild(USB2Connection)

        USB3Connection = register_class.cListDMTerminator(self,
                                                  {'name': 'USB3 Connection',
                                                   'offset': 5,
                                                   'bit length': 1})

        USB3Connection.help = """Highlights if a USB3.0 Connection is present."""
        USB3Connection.setReportList(['No USB3 connection', 'USB3 connection on SSTx1/Rx1 if upside-up, SSTx2/Rx2 if upside down.'])
        self.dataModel.addChild(USB3Connection)

        USB3Speed = register_class.cListDMTerminator(self,
                                                  {'name': 'USB3 Speed',
                                                   'offset': 6,
                                                   'bit length': 1})

        USB3Speed.help = """highlights the USB3.0 speed capabilities."""
        USB3Speed.setReportList(['USB3 limited to Gen 1 speed (5Gbps)', 'USB3 allowed to Gen 2 speed (10Gbs)'])
        self.dataModel.addChild(USB3Speed)

        USBDataRole = register_class.cListDMTerminator(self,
                                                  {'name': 'USB Data Role',
                                                   'offset': 7,
                                                   'bit length': 1})

        USBDataRole.help = """The Data Role of the USB connection."""
        USBDataRole.setReportList(['DFP', 'UFP'])
        self.dataModel.addChild(USBDataRole)

        DPConnection = register_class.cListDMTerminator(self,
                                                  {'name': 'DisplayPort Connection',
                                                   'offset': 8,
                                                   'bit length': 1})

        DPConnection.help = """Highlights if a DisplayPort Connection has been made"""
        DPConnection.setReportList(['No DisplayPort connection.', 'DisplayPort connection'])
        self.dataModel.addChild(DPConnection)

        DPSourceSink = register_class.cListDMTerminator(self,
                                                  {'name': 'DisplayPort Source or Sink',
                                                   'offset': 9,
                                                   'bit length': 1})

        DPSourceSink.help = """Highlights if the DisplayPort Connection is a Source or Sink role."""
        DPSourceSink.setReportList(['DP Source (DFP_D) connection requested (if supported by configuration).', 'DP Sink (UFP_D) connection requested (if supported by configuration).'])
        self.dataModel.addChild(DPSourceSink)

        DPPinAssignment = register_class.cListDMTerminator(self,
                                                  {'name': 'DisplayPort Pin Assignment',
                                                   'offset': 10,
                                                   'bit length': 2})

        DPPinAssignment.help = """Highlights the pin assignment of the DisplayPort connection"""
        DPPinAssignment.setReportList(['Legacy DP, USB-C to DP cable (spec pin assignments E-F, if supported).', 'Legacy DP, USB-C to USB-C cable (spec pin assignments C-D, if supported).', 'New DP, USB-C to USB-C cable (spec pin assignments A-B, if supported).', 'Reserved'])
        self.dataModel.addChild(DPPinAssignment)

        IRQAck = register_class.cListDMTerminator(self,
                                                  {'name': 'IRQ Ack',
                                                   'offset': 13,
                                                   'bit length': 1})

        IRQAck.help = """IRQ has been acknowledged"""
        IRQAck.setReportList(['No IRQ', 'IRQ'])
        self.dataModel.addChild(IRQAck)

        HPDIRQsticky = register_class.cListDMTerminator(self,
                                                  {'name': 'HPD IRQ sticky',
                                                   'offset': 14,
                                                   'bit length': 1})

        HPDIRQsticky.help = """HPD IRQ from DP Sink connection to Titan Ridge to PD Controller. Cleared when Data_Status.HPD_IRQ_Sticky. Used only for TBT devices. Not used for TBT hosts."""
        HPDIRQsticky.setReportList(['No HPD IRQ', 'HPD IRQ'])
        self.dataModel.addChild(HPDIRQsticky)

        HPDLevel = register_class.cListDMTerminator(self,
                                                  {'name': 'HPD Level',
                                                   'offset': 15,
                                                   'bit length': 1})

        HPDLevel.help = """HPD level from DP Sink connection to Titan Ridge to PD Controller. Used only for TBT devices. Not used for TBT hosts."""
        HPDLevel.setReportList(['HPD Low', 'HPD High'])
        self.dataModel.addChild(HPDLevel)

        TBTConnection = register_class.cListDMTerminator(self,
                                                  {'name': 'TBT Connection',
                                                   'offset': 16,
                                                   'bit length': 1})

        TBTConnection.help = """Status of the Thunderbolt Connection."""
        TBTConnection.setReportList(['No Thunderbolt connection. This value is also used if TBT Mode is active but an Attention SVDM has been sent/received enabling USB2 instead of TBT.', 'Thunderbolt connection'])
        self.dataModel.addChild(TBTConnection)

        TBTType = register_class.cListDMTerminator(self,
                                                  {'name': 'TBT Type',
                                                   'offset': 17,
                                                   'bit length': 1})

        TBTType.help = """Status of the Thunderbolt Connection."""
        TBTType.setReportList(['Type-C to Type-C Cable', 'Legacy Adapter'])
        self.dataModel.addChild(TBTType)

        CableType = register_class.cListDMTerminator(self,
                                                  {'name': 'Cable Type',
                                                   'offset': 18,
                                                   'bit length': 1})

        CableType.help = """Status of the Thunderbolt Connection."""
        CableType.setReportList(['Type-C to Type-C Cable', 'Legacy Adapter'])
        self.dataModel.addChild(CableType)

        activeCable = register_class.cListDMTerminator(self,
                                                  {'name': 'Active Cable',
                                                   'offset': 19,
                                                   'bit length': 1})

        CableType.help = """Status of the Thunderbolt Connection."""
        CableType.setReportList(['Active Cable', 'Passive Cable'])
        self.dataModel.addChild(CableType)

        ActiveLinkTraining = register_class.cListDMTerminator(self,
                                                  {'name': 'Active Link Training',
                                                   'offset': 20,
                                                   'bit length': 1})

        ActiveLinkTraining.help = """Status of Active Link Training connection."""
        ActiveLinkTraining.setReportList(['Active with bi-directional LSRX communication (also used for passive cables)', 'Active with uni-directional LSRX communication'])
        self.dataModel.addChild(ActiveLinkTraining)

        ForceLSX = register_class.cListDMTerminator(self,
                                                  {'name': 'Force LSX',
                                                   'offset': 23,
                                                   'bit length': 1})

        ForceLSX.help = """Force LSX"""
        ForceLSX.setReportList(['Normal operation.', 'Force LSX connection active, regardless of TBT operation'])
        self.dataModel.addChild(ForceLSX)

        S0PowerNegotiated = register_class.cListDMTerminator(self,
                                                  {'name': 'S0 Power Negotiated',
                                                   'offset': 24,
                                                   'bit length': 1})

        S0PowerNegotiated.help = """Displays if a power mismatch has occurred."""
        S0PowerNegotiated.setReportList(['Active contract does not have a power mismatch or PD Controller is not a Sink', 'Active contract (as a Sink) has a power mismatch. Not enough power for S0.'])
        self.dataModel.addChild(S0PowerNegotiated)

        TBTCableSpeedSupport = register_class.cListDMTerminator(self,
                                                  {'name': 'Thunderbolt Cable Speed Support',
                                                   'offset': 25,
                                                   'bit length': 3})

        TBTCableSpeedSupport.help = """Displays if a power mismatch has occurred."""
        TBTCableSpeedSupport.setReportList(['Reserved', 'USB3.1 gen1 cable (10Gb/s Thunderbolt support)', '10Gb/s only', '10Gb/s & 20Gb/s only'])
        TBTCableSpeedSupport.setMaxValue(3)
        self.dataModel.addChild(TBTCableSpeedSupport)

        TBTCableGen = register_class.cListDMTerminator(self,
                                                  {'name': 'Thunderbolt Cable Gen',
                                                   'offset': 28,
                                                   'bit length': 2})

        TBTCableGen.help = """Displays if a power mismatch has occurred."""
        TBTCableGen.setReportList(['3rd generation TBT (10.3125 and 20.625 Gb/s)', '4th generation TBT (10.0, 10.3125, 20.0 and 20.625 Gb/s)'])
        TBTCableGen.setMaxValue(1)
        self.dataModel.addChild(TBTCableGen)




class cPolicySettings_0x55_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Policy Settings',
                                                 'address' : 0x55,
                                                 'byte length' : 1,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Policy Settings',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        enVSafe0v = register_class.cBooleanDMTerminator(self,
                                                        {'name' : 'Set VSafe0V to 2V for Disconnect Detection',
                                                         'offset' : 0,
                                                         'bit length' : 1 })
        self.dataModel.addChild(enVSafe0v)

        enGoodCRCNonPref = register_class.cBooleanDMTerminator(self,
															  {'name' : 'Use Non-preferred Specification Revision Bits in Good CRC Message',
															   'offset' : 1,
															   'bit length' : 1 })
        self.dataModel.addChild(enGoodCRCNonPref)






class cRXUserVIDAttnVDM_0x60_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'RX User VID Attention VDM Register',
                                                 'address' : 0x60,
                                                 'byte length' : 29,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'RX User VID Attention VDM Register',
                                                        'offset' : 0,
                                                        'bit length' : 232 })

        rxAttentionStatus = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'RX Attention Status',
                                                        'offset' : 0,
                                                        'bit length' : 232 })

        self.dataModel.addChild(rxAttentionStatus)


        rxVdmNumValid = register_class.cDecimalDMTerminator(self,
                                                            {'name' : 'Number of Valid VDOs',
                                                             'offset' : 0,
                                                             'bit length' : 3 })

        rxVdmNumValid.help = """The number of valid VDOs assigned to this PD Controller."""
        rxVdmNumValid.updateRegisters.append(self)
        rxAttentionStatus.addChild(rxVdmNumValid)

        rxVdmSequenceNum = register_class.cDecimalDMTerminator(self,
                                                            {'name' : 'Number of Register Updates',
                                                             'offset' : 5,
                                                             'bit length' : 3 })

        rxVdmSequenceNum.help = """Increments by one every time this register is updated, rolls over upon reflow."""
        rxVdmSequenceNum.updateRegisters.append(self)
        rxAttentionStatus.addChild(rxVdmSequenceNum)


        rxDataObjects = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Data Objects Received',
                                                        'offset' : 8,
                                                        'bit length' : 224 })

        self.dataModel.addChild(rxDataObjects)

        rxDataObjectOne = cDMAnyFirstVDO(self, 1,
                                                        {'name' : 'Data Object 1',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        rxDataObjects.addChild(rxDataObjectOne)

        for i in range(2,8) :
            dataObjX = register_class.cDataModelArray(self, 1,
                                                            {'name' : 'Data Object %d' %i,
                                                            'offset' : 32 * (i-1),
                                                            'bit length' : 32 })

            rxDataObjects.addChild(dataObjX)

            rxDataObjectX = register_class.cHexDMTerminator(self,
                                                                {'name' : 'Data Object %d' %i,
                                                                 'offset' : 0,
                                                                 'bit length' : 32 })

            rxDataObjectX.help = "Data Object %d of most recently received Attention SVDM." %i
            dataObjX.addChild(rxDataObjectX)

        self.dataModel.setDataModelGenerator(cRxAttention_TopLevelDMGenerator)



########################################################################################################################
########################################################################################################################
########################################################################################################################

class cRXUserVIDOtherVDM_0x61_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'RX User VID Other VDM Register',
                                                 'address' : 0x61,
                                                 'byte length' : 29,
                                                 'permission' : 'DRO'})

        self.dataModel = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'RX User VID Other VDM Register',
                                                        'offset' : 0,
                                                        'bit length' : 232 })



        rxVdmStatus = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'RX VDM Status',
                                                        'offset' : 0,
                                                        'bit length' : 232 })

        self.dataModel.addChild(rxVdmStatus)

        rxVdmNumValid = register_class.cDecimalDMTerminator(self,
                                                            {'name' : 'Number of Valid VDOs',
                                                             'offset' : 0,
                                                             'bit length' : 3 })

        rxVdmNumValid.help = """The number of valid VDOs assigned to this PD Controller."""
        rxVdmNumValid.updateRegisters.append(self)
        rxVdmStatus.addChild(rxVdmNumValid)

        rxVdmSequenceNum = register_class.cDecimalDMTerminator(self,
                                                            {'name' : 'Number of Register Updates',
                                                             'offset' : 5,
                                                             'bit length' : 3 })

        rxVdmSequenceNum.help = """Increments by one every time this register is updated, rolls over upon reflow."""
        rxVdmSequenceNum.updateRegisters.append(self)
        rxVdmStatus.addChild(rxVdmSequenceNum)


        rxDataObjects = register_class.cDataModelArray(self, 2,
                                                        {'name' : 'Data Objects Received',
                                                        'offset' : 8,
                                                        'bit length' : 224 })

        self.dataModel.addChild(rxDataObjects)

        rxDataObjectOne = cDMAnyFirstVDO(self, 1,
                                                        {'name' : 'Data Object 1',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        rxDataObjects.addChild(rxDataObjectOne)

        for i in range(2,8) :
            dataObjX = register_class.cDataModelArray(self, 1,
                                                            {'name' : 'Data Object %d' %i,
                                                            'offset' : 32 * (i-1),
                                                            'bit length' : 32 })

            rxDataObjects.addChild(dataObjX)

            rxDataObjectX = register_class.cHexDMTerminator(self,
                                                                {'name' : 'Data Object %d' %i,
                                                                 'offset' : 0,
                                                                 'bit length' : 32 })

            rxDataObjectX.help = "Data Object %d of most recently received Attention SVDM." %i
            dataObjX.addChild(rxDataObjectX)

        self.dataModel.setDataModelGenerator(cRxVdm_TopLevelDMGenerator)




class cTypeCState_0x69_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Type C State Register',
                                                 'address' : 0x69,
                                                 'byte length' : 4,
                                                 'permission' : 'DRO'})
        # Should permissions be DRO?
        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Type C State Register',
                                                        'offset' : 0,
                                                        'bit length' : 32 })

        CCpinForPD = register_class.cListDMTerminator(self,
                                                        {'name' : 'CC Pin For PD',
                                                         'offset' : 0,
                                                         'bit length' : 8 })
        CCpinForPD.help = """Describes which CC pin is used for PD Communication """
        CCpinForPD.setMaxValue(3)
        CCpinForPD.setReportList(['Not connected', 'C_CC1 is CC pin', 'C_CC2 is CC pin'])
        self.dataModel.addChild(CCpinForPD)

        CC1pinState = register_class.cListDMTerminator(self,
                                                        {'name' : 'CC1 Pin State',
                                                         'offset' : 8,
                                                         'bit length' : 8 })
        CC1pinState.help = """Describes state of CC1 pin"""
        CC1pinState.setMaxValue(5)
        CC1pinState.setReportList(['Not connected', 'Ra detected (Source only)', 'Rd detected (Source only)', 'STD Advertisement detected (Sink only)', '1.5A Advertisement detected (Sink only)', '3.0A Advertisement detected (Sink only)'])
        self.dataModel.addChild(CC1pinState)

        CC2pinState = register_class.cListDMTerminator(self,
                                                        {'name' : 'CC2 Pin State',
                                                         'offset' : 16,
                                                         'bit length' : 8 })
        CC2pinState.help = """Describes state of CC2 pin"""
        CC2pinState.setMaxValue(5)
        CC2pinState.setReportList(['Not connected', 'Ra detected (Source only)', 'Rd detected (Source only)', 'STD Advertisement detected (Sink only)', '1.5A Advertisement detected (Sink only)', '3.0A Advertisement detected (Sink only)'])
        self.dataModel.addChild(CC2pinState)

        TypeCPortState = register_class.cListDMTerminator(self,
                                                        {'name' : 'Type C Port State',
                                                         'offset' : 24,
                                                         'bit length' : 8 })
        TypeCPortState.help = """Describes state of Type C Port"""
        TypeCPortState.setMaxValue(67)
        TypeCPortState.setReportList(['Disabled', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Error Recovery', 'Reserved', 'Reserved', \
                                      'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved',\
                                      'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved',
                                      'Unattached Accessory', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved',\
                                      'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved',
                                      'Reserved', 'Reserved', 'Reserved', 'Attach Wait Accessory', 'Reserved', 'Reserved', 'Reserved', 'Reserved',\
                                      'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved',\
                                      'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved',\
                                      'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Try SRC', 'Reserved', 'Reserved',\
                                      'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Try Wait SNK', 'Try SNK',\
                                      'Try Wait SRC', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved',\
                                      'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved',\
                                      'Attached SRC', 'Attached SNK', 'Audio Accessory', 'Debug Accessory', 'Attach Wait SRC', 'Attach Wait SNK', 'Unattached SNK', 'Unattached SRC'])
        self.dataModel.addChild(TypeCPortState)

########################################################################################################################
########################################################################################################################
########################################################################################################################


class cSleepControl_0x70_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'Sleep Control Register',
                                                 'address' : 0x70,
                                                 'byte length' : 2,
                                                 'permission' : 'RW'})

        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Sleep Control Register',
                                                        'offset' : 0,
                                                        'bit length' : 16 })

        sleepMode = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'Sleep Mode Allowed',
                                                        'offset' : 0,
                                                        'bit length' : 1 })

        self.dataModel.addChild(sleepMode)

        delay100ms = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'Delay 100 mS Before Sleep',
                                                        'offset' : 1,
                                                        'bit length' : 1 })

        self.dataModel.addChild(delay100ms)

        delay1000ms = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'Delay 1000 mS Before Sleep',
                                                        'offset' : 2,
                                                        'bit length' : 1 })

        self.dataModel.addChild(delay1000ms)

        delay30000ms = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'Delay 30000 mS Before Sleep',
                                                        'offset' : 4,
                                                        'bit length' : 1 })

        self.dataModel.addChild(delay30000ms)


        sleepon5Vnonpd = register_class.cBooleanDMTerminator(self,
                                                      {'name' : 'Sleep on 5V non-PD Load',
                                                        'offset' : 3,
                                                        'bit length' : 1 })

        self.dataModel.addChild(sleepon5Vnonpd)

#        sleeponpdconn = register_class.cBooleanDMTerminator(self,
#                                                      {'name' : 'Sleep on PD connected load',
#                                                        'offset' : 5,
#                                                        'bit length' : 1 })

#        self.dataModel.addChild(sleeponpdconn)

        I2Crelaxresp = register_class.cDataModelTerminator(self,
                                                      {'name' : 'I2C Relax Response Level',
                                                        'offset' : 8,
                                                        'bit length' : 8 })

        self.dataModel.addChild(I2Crelaxresp)
########################################################################################################################
########################################################################################################################
########################################################################################################################

class cGPIOStatus_0x72_register(register_class.cRegister) :
    def __init__(self):
        register_class.cRegister.__init__(self, {'register name' : 'GPIO Status Register',
                                                 'address' : 0x72,
                                                 'byte length' : 8,
                                                 'permission' : 'DRO'})

        # Should permissions be DRO?
        self.dataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'GPIO Status Register',
                                                        'offset' : 0,
                                                        'bit length' : 64 })

        for i in range(22):
            GPIO = register_class.cHexDMTerminator(self,
                                                    {'name' : 'GPIO%d Data' %(i) ,
                                                     'offset' : i,
                                                     'bit length' : 1 })
            GPIO.help = """Logic status of GPIO[%d] \n0 - Low \n1 - High""" %(i)
            self.dataModel.addChild(GPIO)


        for i in range(22):
            GPIODir = register_class.cHexDMTerminator(self,
                                                    {'name' : 'GPIO%d Direction' %(i) ,
                                                     'offset' : 32+i,
                                                     'bit length' : 1 })
            GPIODir.help = """Direction of GPIO%d \n0 - Input \n1 - Output""" %(i)
            self.dataModel.addChild(GPIODir)


########################################################################################################################
########################################################################################################################
########################################################################################################################




# host interface function list

task_return_dict = { 0x00000000 : 'SUCCESS_CMD', 0x00000001 : 'ABORT_CMD', 0x00000003 : 'REJECT_CMD' }

class cPDOCurrentField(register_class.cScalingDMTerminator) :
    def __init__(self, register, iDict):
        register_class.cScalingDMTerminator.__init__(self, register, iDict)
        # map all strings representing units to scale factor
        self.dictScaleUnits = {'' : 0.01, 'A' : 0.01, 'mA' : 10.0}
        self.defaultUnit = 'A'


class cPDOVoltageField(register_class.cScalingDMTerminator) :
    def __init__(self, register, iDict):
        register_class.cScalingDMTerminator.__init__(self, register, iDict)
        # map all strings representing units to scale factor
        self.dictScaleUnits = {'' : 0.05, 'V' : 0.05, 'mV' : 50.0}
        self.defaultUnit = 'V'

class cPDOPowerField(register_class.cScalingDMTerminator) :
    def __init__(self, register, iDict):
        register_class.cScalingDMTerminator.__init__(self, register, iDict)
        # map all strings representing units to scale factor
        self.dictScaleUnits = {'' : 0.25, 'W' : 0.25, 'mW' : 250.0}
        self.defaultUnit = 'W'


class cDBfg(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Deadbattery Flag Clear',
                                                 '4cc' : 'DBfg',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cABRT(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Abort',
                                                 '4cc' : 'ABRT',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cGaid(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Warm Reboot',
                                                 '4cc' : 'Gaid',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 0})

        self.inargsDataModel = None
        self.outargsDataModel = None


class cGAID(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Cold Reboot',
                                                 '4cc' : 'GAID',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 0})

        self.inargsDataModel = None
        self.outargsDataModel = None


class cHRST(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'PD Hard Reset',
                                                 '4cc' : 'HRST',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cCRST(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Cable Reset',
                                                 '4cc' : 'CRST',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cGSkC(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Get Sink Capabilities',
                                                 '4cc' : 'GSkC',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cGSrC(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Get Source Capabilities',
                                                 '4cc' : 'GSrC',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cSSrC(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Send Source Capabilities',
                                                 '4cc' : 'SSrC',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cSRDO(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Send Request Data Object',
                                                 '4cc' : 'SRDO',
                                                 'inargs byte length' : 4,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = register_class.cDataModelArray(self, 1,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 32 })


        mmOpCurr = cPDOCurrentField(self.inargsMiniReg, { 'name' : 'Max/Min Operating Current or Power',
                                                                'offset' : 0,
                                                                'bit length' : 10} )
        self.inargsDataModel.addChild(mmOpCurr)

        opCurr = cPDOCurrentField(self.inargsMiniReg, { 'name' : 'Operating Current or Power',
                                                                'offset' : 10,
                                                                'bit length' : 10} )
        self.inargsDataModel.addChild(opCurr)

        noUSBSusp = register_class.cBooleanDMTerminator(self.inargsMiniReg, { 'name' : 'No USB Suspend',
                                                                'offset' : 24,
                                                                'bit length' : 1} )
        self.inargsDataModel.addChild(noUSBSusp)

        USBCommCap = register_class.cBooleanDMTerminator(self.inargsMiniReg, { 'name' : 'USB Communications Capable',
                                                                'offset' : 25,
                                                                'bit length' : 1} )
        self.inargsDataModel.addChild(USBCommCap)

        capMismatch = register_class.cBooleanDMTerminator(self.inargsMiniReg, { 'name' : 'Capability Mismatch',
                                                                'offset' : 26,
                                                                'bit length' : 1} )
        self.inargsDataModel.addChild(capMismatch)

        giveBack = register_class.cBooleanDMTerminator(self.inargsMiniReg, { 'name' : 'Give Back Flag',
                                                                'offset' : 27,
                                                                'bit length' : 1} )
        self.inargsDataModel.addChild(giveBack)

        objPosn = register_class.cDecimalDMTerminator(self.inargsMiniReg, { 'name' : 'Object Position',
                                                                'offset' : 28,
                                                                'bit length' : 3} )
        self.inargsDataModel.addChild(objPosn)



        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)



class cSWSk(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Swap to Sink',
                                                 '4cc' : 'SWSk',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cSWSr(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Swap to Source',
                                                 '4cc' : 'SWSr',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)



class cSWDF(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Swap to DFP',
                                                 '4cc' : 'SWDF',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)



class cSWUF(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Swap to UFP',
                                                 '4cc' : 'SWUF',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)



class cSWVC(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Swap VConn Provider',
                                                 '4cc' : 'SWVC',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cSRDY(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'System Ready to Sink Power',
                                                 '4cc' : 'SRDY',
                                                 'inargs byte length' : 1,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = register_class.cDataModelArray(self.inargsMiniReg, 1,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        swSel = register_class.cListDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'Switch Selection',
                                                            'offset' : 0,
                                                            'bit length' : 2 })
        swSel.setReportList(self.SwitchSelection_list)
        swSel.setMaxValue(2)
        self.inargsDataModel.addChild(swSel)


        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)

    SwitchSelection_list = ['Reserved', 'PP_HV', 'PP_HVE']


class cAMEn(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Enter Alternate Mode',
                                                 '4cc' : 'AMEn',
                                                 'inargs byte length' : 5,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = register_class.cDataModelArray(self.inargsMiniReg, 1,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 40 })

        SVID = register_class.cHexDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'SVID',
                                                            'offset' : 0,
                                                            'bit length' : 32 })
        self.inargsDataModel.addChild(SVID)

        objPosn = register_class.cDecimalDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'Object Position',
                                                            'offset' : 32,
                                                            'bit length' : 3 })
        self.inargsDataModel.addChild(objPosn)


        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)



class cAMEx(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Exit Alternate Mode',
                                                 '4cc' : 'AMEx',
                                                 'inargs byte length' : 5,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = register_class.cDataModelArray(self.inargsMiniReg, 1,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 40 })

        SVID = register_class.cHexDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'SVID',
                                                            'offset' : 0,
                                                            'bit length' : 32 })
        self.inargsDataModel.addChild(SVID)

        objPosn = register_class.cDecimalDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'Object Position',
                                                            'offset' : 32,
                                                            'bit length' : 3 })
        self.inargsDataModel.addChild(objPosn)


        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)



class cANEG(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Autonegotiate Sink',
                                                 '4cc' : 'ANEG',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cAMDs(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Start Alternate Mode Discovery',
                                                 '4cc' : 'AMDs',
                                                 'inargs byte length' : 0,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = None
        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cGPie(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Enable GPIO as Input',
                                                 '4cc' : 'GPie',
                                                 'inargs byte length' : 1,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = register_class.cDataModelArray(self.inargsMiniReg, 1,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        gpioNum = register_class.cDecimalDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'GPIO Number',
                                                            'offset' : 0,
                                                            'bit length' : 8 })
        gpioNum.setMaxValue(21)
        self.inargsDataModel.addChild(gpioNum)


        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


class cGPoe(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Enable GPIO as Output',
                                                 '4cc' : 'GPoe',
                                                 'inargs byte length' : 1,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = register_class.cDataModelArray(self.inargsMiniReg, 1,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        gpioNum = register_class.cDecimalDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'GPIO Number',
                                                            'offset' : 0,
                                                            'bit length' : 8 })
        gpioNum.setMaxValue(21)
        self.inargsDataModel.addChild(gpioNum)


        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)



class cGPsh(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Set GPIO High',
                                                 '4cc' : 'GPsh',
                                                 'inargs byte length' : 1,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = register_class.cDataModelArray(self.inargsMiniReg, 1,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        gpioNum = register_class.cDecimalDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'GPIO Number',
                                                            'offset' : 0,
                                                            'bit length' : 8 })
        gpioNum.setMaxValue(21)
        self.inargsDataModel.addChild(gpioNum)


        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)



class cGPsl(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Set GPIO Low',
                                                 '4cc' : 'GPsl',
                                                 'inargs byte length' : 1,
                                                 'outargs byte length' : 1})

        self.inargsDataModel = register_class.cDataModelArray(self.inargsMiniReg, 1,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        gpioNum = register_class.cDecimalDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'GPIO Number',
                                                            'offset' : 0,
                                                            'bit length' : 8 })
        gpioNum.setMaxValue(21)
        self.inargsDataModel.addChild(gpioNum)


        self.outargsDataModel = register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)

# display pdos based on numPdo
# not a method, but should be grouped with txSrcCap class
def VDMs_inargs_TopLevelDMGenerator(self) :
    numVdo = self.getChildByName('Number of 32-bit VDM Objects').valueToInt()

    for i in range(7) :
        if i < numVdo :
            self.getChildByName('VDO %d Payload (32-bit)' %(i+1)).unhide()
        else :
            self.getChildByName('VDO %d Payload (32-bit)' %(i+1)).hide()

    return self.childrenAsListDMGenerator()

class cVDMs(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'Send VDM Packet',
                                                 '4cc' : 'VDMs',
                                                 'inargs byte length' : 29,
                                                 'outargs byte length' : 1})

        self.setInputModel ( register_class.cDataModelArray(self.inargsMiniReg, 2,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 8 }) )

        self.inargsArray = register_class.cDataModelArray(self.inargsMiniReg, 1,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        self.inargsDataModel.addChild(self.inargsArray)

        numObj = register_class.cDecimalDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'Number of 32-bit VDM Objects',
                                                            'offset' : 0,
                                                            'bit length' : 3 })
        numObj.setMaxValue(7)
        numObj.addUpdateRegisterByName('self')
        self.inargsArray.addChild(numObj)

        sopType = register_class.cListDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'SOP Type',
                                                            'offset' : 4,
                                                            'bit length' : 2 })
        sopType.setReportList(self.sop_type_list)
        sopType.setMaxValue(2)
        self.inargsArray.addChild(sopType)

        structType = register_class.cListDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'Structured/Unstructured',
                                                            'offset' : 23,
                                                            'bit length' : 1 })
        structType.setReportList(self.structured_type_list)
        self.inargsArray.addChild(structType)

        SVID = register_class.cHexDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'SVID (Standard or Vendor ID)',
                                                            'offset' : 24,
                                                            'bit length' : 16 })
        self.inargsArray.addChild(SVID)

        vdo0 = register_class.cHexDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'VDO 0 Partial Payload (15-bit)',
                                                            'offset' : 8,
                                                            'bit length' : 15 })
        self.inargsArray.addChild(vdo0)


        for i in range(1,8) :
            vdox = register_class.cHexDMTerminator(self.inargsMiniReg,
                                                              {'name' : 'VDO %d Payload (32-bit)' %i,
                                                                'offset' : 8 + (32 * i),
                                                                'bit length' : 32 })
            self.inargsArray.addChild(vdox)


        self.inargsArray.setDataModelGenerator(VDMs_inargs_TopLevelDMGenerator)

        self.setOutputModel( register_class.cDataModelArray(self.outargsMiniReg, 2,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 8 }))

        TSKReturn = register_class.cDictDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Task Return Status',
                                                            'offset' : 0,
                                                            'bit length' : 8 })

        TSKReturn.setReportDict(task_return_dict)
        TSKReturn.lock()
        self.outargsDataModel.addChild(TSKReturn)


    sop_type_list = ['SOP', 'SOP Prime', 'SOP Double-Prime']
    structured_type_list = ['Unstructured VDM', 'Structured VDM']


ADCchannelListOfDict = [ { 'Channel' : 'Thermal Sensor Temperature', 'Divider Ratio' : 1024 / 1.2, 'Unit' : 'Raw (1024 LSB scale)' }, \
    { 'Channel' : 'VBUS Voltage', 'Divider Ratio' : 25, 'Unit' : 'V' }, \
    { 'Channel' : 'SENSEP', 'Divider Ratio' : 25, 'Unit' : 'V' }, \
    { 'Channel' : 'PP_EXT Current', 'Divider Ratio' : 5, 'Unit' : 'A' }, \
    { 'Channel' : 'PP_HV Voltage', 'Divider Ratio' : 25, 'Unit' : 'V' }, \
    { 'Channel' : 'PP_HV Current', 'Divider Ratio' : 3, 'Unit' : 'A' }, \
    { 'Channel' : 'PP 5V Voltage', 'Divider Ratio' : 5, 'Unit' : 'V' }, \
    { 'Channel' : 'PP_5V Current', 'Divider Ratio' : 3, 'Unit' : 'A' }, \
    { 'Channel' : 'CC1 Voltage (divide by 5)', 'Divider Ratio' : 5, 'Unit' : 'V' }, \
    { 'Channel' : 'I_CC', 'Divider Ratio' : 0.7, 'Unit' : 'V' }, \
    { 'Channel' : 'CC2 Voltage (divide by 5)', 'Divider Ratio' : 5, 'Unit' : 'V' }, \
    { 'Channel' : 'GPIO 5', 'Divider Ratio' : 1, 'Unit' : 'V' }, \
    { 'Channel' : 'CC1 Voltage (divide by 2)', 'Divider Ratio' : 2, 'Unit' : 'V' }, \
    { 'Channel' : 'CC2 Voltage (divide by 2)', 'Divider Ratio' : 2, 'Unit' : 'V' }, \
    { 'Channel' : 'PP_Cable', 'Divider Ratio' : 5, 'Unit' : 'V' }, \
    { 'Channel' : 'VIN_3V3', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'VOUT_3V3', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'Brick ID', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'V1P8D', 'Divider Ratio' : 2, 'Unit' : 'V' }, \
    { 'Channel' : 'V1P8A', 'Divider Ratio' : 2, 'Unit' : 'V' }, \
    { 'Channel' : 'V3P3', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'I2CADDR', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'GPIO_0', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'GPIO_1', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'GPIO_2', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'GPIO_3', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'GPIO_4', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'GPIO_5', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'GPIO_6', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'GPIO_7', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'GPIO_8', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    { 'Channel' : 'BUSPOWER_Z', 'Divider Ratio' : 3, 'Unit' : 'V' }, \
    ]


class cDMAnyChannelTerminator(register_class.cDataModelTerminator) :
    def __init__(self, register, adcFunction, iDict):
        register_class.cDataModelTerminator.__init__(self, register, iDict)
        self.adcFunction = adcFunction
        self.terminatorOverlayList = []

        for channel in ADCchannelListOfDict :
            channelTerm = register_class.cScalingDMTerminator(self.register,
                                                          {'name' : iDict['name'],
                                                            'offset' : iDict['offset'],
                                                            'bit length' : iDict['bit length'] })
            ratio = ( (1.2) / 1024 ) * channel['Divider Ratio']
            channelTerm.dictScaleUnits = {'' : ratio, channel['Unit'] : ratio}
            channelTerm.defaultUnit = channel['Unit']

            self.terminatorOverlayList.append(channelTerm)


        self.dataModelGenerator = self.AnyScalerGenerator


    def AnyScalerGenerator(self):
        # todo: should make a set parent call instead of allowing to be set directly
        #       then the objects can correctly set sub-object parent relationships
        for term in self.terminatorOverlayList :
            term.parent = self.parent

        channel = self.adcFunction.inargsDataModel.getChildByName('Channel').valueToInt()
        dmGenerator = self.terminatorOverlayList[channel]

        return dmGenerator.dataModelGenerator()

    def lock(self) :
        for term in self.terminatorOverlayList :
            term.lock()


class cADCs(function_class.cFunction) :
    def __init__(self):
        function_class.cFunction.__init__(self, {'function name' : 'ADC Read',
                                                 '4cc' : 'ADCs',
                                                 'inargs byte length' : 1,
                                                 'outargs byte length' : 3})



        self.channelList = []
        for record in ADCchannelListOfDict :
            self.channelList.append(record['Channel'])

        inargsDM = register_class.cDataModelArray(self.inargsMiniReg, 1,
                                                        {'name' : 'Input Arguments',
                                                        'offset' : 0,
                                                        'bit length' : 8 })

        channel = register_class.cListDMTerminator(self.inargsMiniReg,
                                                          {'name' : 'Channel',
                                                            'offset' : 0,
                                                            'bit length' : 5 })
        channel.setReportList(self.channelList)
        channel.setMaxValue(23)
        inargsDM.addChild(channel)

        self.setInputModel(inargsDM)


        outargsDM = register_class.cDataModelArray(self.outargsMiniReg, 1,
                                                        {'name' : 'Return Values',
                                                        'offset' : 0,
                                                        'bit length' : 24 })

        channelRead = register_class.cListDMTerminator(self.outargsMiniReg,
                                                          {'name' : 'Channel',
                                                            'offset' : 0,
                                                            'bit length' : 5 })
        channelRead.setReportList(self.channelList)
        channelRead.setMaxValue(23)
        outargsDM.addChild(channelRead)
        channelRead.lock()

        TSKReturn = cDMAnyChannelTerminator(self.outargsMiniReg, self,
                                                          {'name' : 'ADC Read Value',
                                                            'offset' : 8,
                                                            'bit length' : 10 })

        TSKReturn.lock()
        outargsDM.addChild(TSKReturn)

        self.setOutputModel(outargsDM)



def getBootStatus(handle, device_rw, command, data):
    device_rw.write_reg(handle, 0x09, byteArray(0))
    device_rw.write_reg_4cc(handle, 0x08, 'FLrr')
    retVal = verify_cmd_completed(handle, device_rw)
    if retVal != "Success" :
        return {'status': -2, 'message' : retVal}
    (count, readArray) = device_rw.read_reg(handle, 0x09, 5)
    if len(readArray) >= 4 :
        region0Addr = readArray[0] | (readArray[1] << 8) | (readArray[2] << 16) | (readArray[3] << 24)
    else :
        return {'status': -2, 'message' : 'Read failure from device'}

    device_rw.write_reg(handle, 0x09, byteArray(1))
    device_rw.write_reg_4cc(handle, 0x08, 'FLrr')
    retVal = verify_cmd_completed(handle, device_rw)
    if retVal != "Success" :
        return {'status': -2, 'message' : retVal}
    (count, readArray) = device_rw.read_reg(handle, 0x09, 5)
    if len(readArray) >= 4 :
        region1Addr = readArray[0] | (readArray[1] << 8) | (readArray[2] << 16) | (readArray[3] << 24)
    else :
        return {'status': -2, 'message' : 'Read failure from device'}

    (count, readArray) = device_rw.read_reg(handle, 0x2D, 5)

    if readArray[0] & 0x8 == 0x8 :
        spiPresent = True
    else :
        spiPresent = False

    if readArray[1] & 0x1 == 0x1 :
        region1Attempted = True
    else :
        region1Attempted = False

    (count, readArray) = device_rw.read_reg(handle, 0x03, 5)

    mode = ''.join([chr(b) for b in readArray])

    if mode == 'APP ' :
        booted = True
    else :
        booted = False

    if booted and spiPresent :
        if region1Attempted == True :
            bootRegion = 1
        else :
            bootRegion = 0
    else :
        bootRegion = -1

    return {'status': 0, 'message' : 'Success', 'return data' : (region0Addr, region1Addr, bootRegion)}


def erase4KBlock(handle, device_rw, command, data) :
    startAddr = data['Start Address']
    if startAddr & 0xFFF != 0x0 :
        return {'status': -2, 'message' : 'Start Address must have a block offset (multiple of 0x1000)'}

    sAByteArray = byteArray(startAddr)
    while len(sAByteArray) < 4 :
        sAByteArray.append(0)

    sAByteArray.append(1)


    # erase the block
    device_rw.write_reg(handle, 0x09, sAByteArray)
    device_rw.write_reg_4cc(handle, 0x08, 'FLem')
    retVal = verify_cmd_completed(handle, device_rw)

    if retVal == "Success" :
        return {'status': 0, 'message' : 'Success'}
    else :
        return {'status': -2, 'message' : retVal}


def write64BBlock(handle, device_rw, command, data) :
    startAddr = data['Start Address']
    writeData = data['Write Data']

    if startAddr % 64 != 0 :
        return {'status': -2, 'message' : 'Start Address must be a multiple of 64' }

    if len(writeData) != 64 :
        return {'status': -2, 'message' : 'Write data size must be exactly 64. Received data of size %d' %len(writeData) }

    sAByteArray = byteArray(startAddr)
    while len(sAByteArray) < 4 :
        sAByteArray.append(0)

    # set the write pointer
    device_rw.write_reg(handle, 0x09, sAByteArray)
    device_rw.write_reg_4cc(handle, 0x08, 'FLad')
    retVal = verify_cmd_completed(handle, device_rw)

    if retVal != "Success" :
        return {'status': -1, 'message' : retVal}

    MAX_RETRIES = 3
    retries1 = 0
    retries2 = 0
    match = False
    while (retries1 < MAX_RETRIES ) :
        while (retries2 < MAX_RETRIES ) and ( match == False ) :
            device_rw.write_reg(handle, 0x09, writeData)
            time.sleep(0.010)
            (count, matchData) = device_rw.read_reg( handle, 0x09, 65 )
            match = True
            for i in range(64) :
                if matchData[i] != writeData[i] :
                    match = False
            retries2 += 1

        if retries2 == MAX_RETRIES :
            return {'status': -3, 'message' : 'Flash write failure.  Maximum retries reached.'}

        print 'match'
        retries2 = 0
        device_rw.write_reg_4cc(handle, 0x08, 'FLwd')
        retVal = verify_cmd_completed(handle, device_rw)
        if retVal != "Success" :
            retries1 += 1
        else :
            (count, readArray) = device_rw.read_reg(handle, 0x09, 2)
            if readArray[0] != 0 :
                retries1 += 1
            else :
                retries1 = -1
                break

    if retries1 == MAX_RETRIES :
        if retval != "Success" :
            return {'status': -1, 'message' : retVal}
        else :
            return {'status': -3, 'message' : 'Flash write failure.  Maximum retries reached. Error code %d' %readArray[0]}

    return {'status': 0, 'message' : 'Success'}



def read16BBlock(handle, device_rw, command, data) :
    startAddr = data['Start Address']

    readAddr = byteArray(startAddr)
    while len(readAddr) < 4 :
        readAddr.append(0)

    device_rw.write_reg(handle, 0x09, readAddr)
    device_rw.write_reg_4cc(handle, 0x08, 'FLrd')
    retVal = verify_cmd_completed(handle, device_rw)
    if retVal != "Success" :
        return {'status': -2, 'message' : retVal}
    (count, readArray) = device_rw.read_reg(handle, 0x09, 17)

    return {'status': 0, 'message' : 'Success', 'Read Data' : readArray}


def reboot(handle, device_rw, command, data) :
    device_rw.write_reg_4cc(handle, 0x08, 'GAID')
    # there is no verification step when rebooting
    return {'status': 0, 'message' : 'Reboot request sent'}

def HIFirmwareUpdate(handle, device_rw, command, data) :
    # return an array of strings in case someone wants to organize by line
    if command == 'getBootStatus' :
        return getBootStatus(handle, device_rw, command, data)

    if command == 'erase4KBlock' :
        return erase4KBlock(handle, device_rw, command, data)

    if command == 'write64BBlock' :
        return write64BBlock(handle, device_rw, command, data)

    if command == 'read16BBlock' :
        return read16BBlock(handle, device_rw, command, data)

    if command == 'reboot' :
        return reboot(handle, device_rw, command, data)

    return {'status': -1, 'message' : 'Command not recognized'}



templateDevice = "TPS65981"
templateVersion = "2.14"

# String Table Definitions
stringTableListofDict = [ {'name' : 'iSerialNumber', 'default' : '01.00.00'}, \
                {'name' : 'iProduct', 'default' : 'TPS65982'}, \
                {'name' : 'iManufacturer', 'default' : 'Texas Instruments'}, \
                {'name' : 'iAdditionalInfoURL', 'default' : 'http://www.ti.com/product/TPS65982'}, \
                {'name' : 'TBT string', 'default' : 'Thunderbolt Mode Entry Error'}, \
                {'name' : 'DP string', 'default' : 'HTTP://help.vesa.org/dp-usb-type-c'} ]


zeroOneList = [ '0', '1' ]
i2cAddrList = [ '0 (0 Ohm R_d)', \
                '1 (93.1 KOhm R_d)', \
                '2 (156 KOhm R_d)', \
                '3 (220 KOhm R_d)', \
                '4 (280 KOhm R_d)', \
                '5 (340 KOhm R_d)', \
                '6 (402 KOhm R_d)', \
                '7 (Open)', \
              ]

def dbg1ValueFromAddr(strapping) :
    return (strapping >> 4) & 0x1

def dbg2ValueFromAddr(strapping) :
    return (strapping >> 3) & 0x1

def i2cAddrValueFromAddr(strapping) :
    return (strapping) & 0x7

def indexOfName(name, deviceStrappingValuesListOfDict) :
    for (i, record) in enumerate(deviceStrappingValuesListOfDict) :
        if record['name'] == name :
            return i

    return None

def tps65982_addr_function(portNum, deviceStrappingValuesListOfDict) :
    dbg1Value = deviceStrappingValuesListOfDict[indexOfName('DBG_CTL1', deviceStrappingValuesListOfDict)]['value']
    dbg2Value = deviceStrappingValuesListOfDict[indexOfName('DBG_CTL2', deviceStrappingValuesListOfDict)]['value']
    i2cAddrValue = deviceStrappingValuesListOfDict[indexOfName('I2C_ADDR', deviceStrappingValuesListOfDict)]['value']

    assert portNum == 0

    addr = 0
    addr |= dbg1Value << 4
    addr |= dbg2Value << 3
    addr |= i2cAddrValue

    return addr
# 1-byte selection bitfield if 3 bits in address
# 4-byte selection bitfield if 5 bits in address
numBitsDeviceAddress = 5

def tps65983_addr_function_i2c1(portNum, deviceStrappingValuesListOfDict) :
    index = indexOfName('DBG_CTL1', deviceStrappingValuesListOfDict)
    if index == None :
        dbg1Value = 0
    else :
        dbg1Value = deviceStrappingValuesListOfDict[index]['value']

    index = indexOfName('DBG_CTL2', deviceStrappingValuesListOfDict)
    if index == None :
        dbg2Value = 0
    else :
        dbg2Value = deviceStrappingValuesListOfDict[index]['value']

    index = indexOfName('I2C_ADDR', deviceStrappingValuesListOfDict)
    if index == None :
        i2cAddrValue = 0
    else :
        i2cAddrValue = deviceStrappingValuesListOfDict[index]['value']

    addr = 0
    addr |= dbg1Value << 4
    addr |= dbg2Value << 3
    addr |= i2cAddrValue
    addr |= portNum << 2

    addr |= 0x38

    return addr


def tps65983_addr_function_i2c2(portNum, deviceStrappingValuesListOfDict) :
    index = indexOfName('DBG_CTL1', deviceStrappingValuesListOfDict)
    if index == None :
        dbg1Value = 0
    else :
        dbg1Value = deviceStrappingValuesListOfDict[index]['value']

    index = indexOfName('DBG_CTL2', deviceStrappingValuesListOfDict)
    if index == None :
        dbg2Value = 0
    else :
        dbg2Value = deviceStrappingValuesListOfDict[index]['value']

    index = indexOfName('I2C_ADDR', deviceStrappingValuesListOfDict)
    if index == None :
        i2cAddrValue = 0
    else :
        i2cAddrValue = deviceStrappingValuesListOfDict[index]['value']

    addr = 0
    addr |= dbg1Value << 4
    addr |= dbg2Value << 3
    addr |= i2cAddrValue
    addr |= portNum << 2

    addr |= 0x20

    return addr



deviceStrappingListOfDict = [ \
                    {'name' : 'DBG_CTL1', 'type' : 'pulldown', 'option list' : zeroOneList, 'value function' : dbg1ValueFromAddr }, \
                    {'name' : 'DBG_CTL2', 'type' : 'pulldown', 'option list' : zeroOneList, 'value function' : dbg2ValueFromAddr }, \
                    {'name' : 'I2C_ADDR', 'type' : 'pulldown', 'option list' : i2cAddrList, 'value function' : i2cAddrValueFromAddr }, \
                ]

devicePortsListOfDict = [ \
                {'name' : 'Port1', 'port value' : 0 , 'addr function' : tps65982_addr_function, 'addr function I2C1' : tps65983_addr_function_i2c1, 'addr function I2C2' : tps65983_addr_function_i2c2 }, \
                ]


virtualStrappingListOfDict = [ \
                    {'name' : 'DBG_CTL1', 'type' : 'pulldown', 'option list' : zeroOneList, 'value function' : dbg1ValueFromAddr }, \
                    {'name' : 'DBG_CTL2', 'type' : 'pulldown', 'option list' : zeroOneList, 'value function' : dbg2ValueFromAddr }, \
                    {'name' : 'I2C_ADDR', 'type' : 'pulldown', 'option list' : i2cAddrList, 'value function' : i2cAddrValueFromAddr }, \
                ]

virtualPortsListOfDict = [ \
                {'name' : 'Port1', 'port value' : 0 , 'addr function' : tps65982_addr_function }, \
                ]


# device definitions
allAceDevice = register_class.cDevice({'I2C address' : 0x38, 'ports' : devicePortsListOfDict, 'strapping' : deviceStrappingListOfDict})
allAceDevice.addRegister(cCustUse_0x06_register())
allAceDevice.configureDerivedFields()
allAceDevice.hide()

NUM_PHYSICAL_DEVICES = 2
oneAceDeviceList = []
for i in range(NUM_PHYSICAL_DEVICES) :
    device = register_class.cDevice({'I2C address' : 0x38, 'ports' : devicePortsListOfDict, 'strapping' : deviceStrappingListOfDict})
    device.setHIFirmwareUpdateFunction(HIFirmwareUpdate)
    device.addRegister(cMode_0x03_register())
    device.addRegister(cCustUse_0x06_register())
    device.addRegister(cVersion_0x0f_register())
    device.addRegister(cIntMask1_0x16_register())
    device.addRegister(cIntMask2_0x17_register())
    device.addRegister(cStatus_0x1A_register())
    device.addRegister(cSystemPowerState_0x20_register())
    device.addRegister(cSysConfig_0x28_register())
    device.addRegister(cControlConfig_0x29_register())
    device.addRegister(cBootFlags_0x2D_register())
    device.addRegister(cBuildID_0x2E_register())
    device.addRegister(cDeviceInfo_0x2F_register())
    device.addRegister(cRxSrcCap_0x30_register())
    device.addRegister(cRxSinkCap_0x31_register())
    device.addRegister(cTxSrcCap_0x32_register())
    device.addRegister(cTxSinkCap_0x33_register())
    device.addRegister(cActiveContractPDO_0x34_register())
    device.addRegister(cActiveContractRDO_0x35_register())
    device.addRegister(cSinkRequestRDO_0x36_register())
    device.addRegister(cAutoNegSink_0x37_register())
    device.addRegister(cAltModeEntryQueue_0x38_register())
    device.addRegister(cPowerStatus_0x3F_register())
    device.addRegister(cPDStatus_0x40_register())
    device.addRegister(cTxIDO_0x47_register())
    device.addRegister(cRxIDO_SOP_0x48_register())
    device.addRegister(cRxIDO_SOPPrime_0x49_register())
    device.addRegister(cUserSvidConfig_0x4A_register())
    device.addRegister(cRxAttention_0x4E_register())
    device.addRegister(cRxVdm_0x4F_register())
    device.addRegister(cDataControl_0x50_register())
    device.addRegister(cDisplayPortCapabilities_0x51_register())
    device.addRegister(cIntVidConf_0x52_register())
    device.addRegister(cTIVidConf_0x54_register())
    device.addRegister(cUserVidStatus_0x57_register())
    device.addRegister(cDPSIDStatus_0x58_register())
    device.addRegister(cIntelVIDStatus_0x59_register())
    device.addRegister(cTiVidStatus_0x5B_register())
    device.addRegister(cGPIOEventMap_0x5C_register())
    device.addRegister(cGPIOEventMap_0x5D_register())
    device.addRegister(cMiscellaneous_0x5E_register())
    device.addRegister(cDataStatus_0x5F_register())
    device.addRegister(cRXUserVIDAttnVDM_0x60_register())
    device.addRegister(cRXUserVIDOtherVDM_0x61_register())
    device.addRegister(cTypeCState_0x69_register())
    device.addRegister(cSleepControl_0x70_register())
    device.addRegister(cGPIOStatus_0x72_register())

    device.addHIFunction(function_class.cRawRead())
    device.addHIFunction(function_class.cRawWrite())
    device.addHIFunction(cDBfg())
    device.addHIFunction(cABRT())
    device.addHIFunction(cGaid())
    device.addHIFunction(cGAID())
    device.addHIFunction(cHRST())
    device.addHIFunction(cCRST())
    device.addHIFunction(cGSkC())
    device.addHIFunction(cGSrC())
    device.addHIFunction(cSSrC())
    device.addHIFunction(cSRDO())
    device.addHIFunction(cSWSk())
    device.addHIFunction(cSWSr())
    device.addHIFunction(cSWDF())
    device.addHIFunction(cSWUF())
    device.addHIFunction(cSWVC())
    device.addHIFunction(cSRDY())
    device.addHIFunction(cAMEn())
    device.addHIFunction(cAMEx())
    device.addHIFunction(cANEG())
    device.addHIFunction(cAMDs())
    device.addHIFunction(cGPie())
    device.addHIFunction(cGPoe())
    device.addHIFunction(cGPsh())
    device.addHIFunction(cGPsl())
    device.addHIFunction(cVDMs())
    device.addHIFunction(cADCs())

    device.configureDerivedFields()
    oneAceDeviceList.append(device)


NUM_VIRTUAL_DEVICES = 6
virtualDeviceList = []
for i in range(NUM_PHYSICAL_DEVICES, NUM_PHYSICAL_DEVICES + NUM_VIRTUAL_DEVICES) :
    device = register_class.cDevice({'I2C address' : 0x38, 'ports' : virtualPortsListOfDict, 'strapping' : virtualStrappingListOfDict, 'is virtual' : True })
    newReg = cCustUse_0x06_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cData1_0x09_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cData2_0x11_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cData3_0x1F_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cIntMask1_0x16_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cIntMask2_0x17_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cSystemPowerState_0x20_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cSysConfig_0x28_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cControlConfig_0x29_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cTxSrcCap_0x32_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cTxSinkCap_0x33_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cAutoNegSink_0x37_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cAltModeEntryQueue_0x38_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cTxIDO_0x47_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cUserSvidConfig_0x4A_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cDisplayPortCapabilities_0x51_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cIntVidConf_0x52_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cTIVidConf_0x54_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cGPIOEventMap_0x5C_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cGPIOEventMap_0x5D_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cMiscellaneous_0x5E_register()
    newReg.unselect()
    device.addRegister(newReg)
    newReg = cSleepControl_0x70_register()
    newReg.unselect()
    device.addRegister(newReg)
    device.configureDerivedFields()
    virtualDeviceList.append(device)



ACE_register_definition_metadata_json_delimiter{"virtual device list of dict": [{"show": 0, "name": "Virtual Device 1", "addr": 56}, {"show": 0, "name": "Virtual Device 2", "addr": 56}, {"show": 0, "name": "Virtual Device 3", "addr": 56}, {"show": 0, "name": "Virtual Device 4", "addr": 56}, {"show": 0, "name": "Virtual Device 5", "addr": 56}, {"show": 0, "name": "Virtual Device 6", "addr": 56}], "firmware filename": "TPS65981_2_6_v0001_12_08.bin", "device list of dict": [{"show": 1, "name": "Device 1", "addr": 0}, {"show": 0, "name": "Device 2", "addr": 1}], "configuration values": "{\"meta\": {\"project\": 1, \"version\": 1}, \"data\": {\"every_ace\": [{\"register\": 6, \"data\": [7, 2, 0, 0, 0, 0, 0, 0]}], \"header\": {\"usb_if_xid\": 0, \"unlock_code\": \"CST1\", \"customer_version\": 0, \"protection_flags\": 250}, \"bin_table\": [], \"strings\": [{\"is_ascii\": true, \"is_valid\": true, \"string\": \"01.00.00\"}, {\"is_ascii\": true, \"is_valid\": true, \"string\": \"TPS65982\"}, {\"is_ascii\": true, \"is_valid\": true, \"string\": \"Texas Instruments\"}, {\"is_ascii\": true, \"is_valid\": true, \"string\": \"http://www.ti.com/product/TPS65982\"}, {\"is_ascii\": true, \"is_valid\": true, \"string\": \"Thunderbolt Mode Entry Error\"}, {\"is_ascii\": true, \"is_valid\": true, \"string\": \"HTTP://help.vesa.org/dp-usb-type-c\"}], \"selected_ace\": [{\"rights\": 0, \"register\": 6, \"data\": [0, 0, 0, 0, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 22, \"data\": [8, 0, 0, 2, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 23, \"data\": [8, 0, 0, 2, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 32, \"data\": [0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 40, \"data\": [141, 3, 63, 33, 247, 8, 21, 42, 216, 0, 157, 5, 6, 0, 0, 20, 20, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 41, \"data\": [80, 196, 0, 113, 7], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 50, \"data\": [1, 252, 0, 44, 145, 1, 38, 44, 193, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 51, \"data\": [2, 90, 144, 1, 38, 90, 192, 3, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 105, 1, 64, 44, 105, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 55, \"data\": [95, 1, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 56, \"data\": [1, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 71, \"data\": [3, 81, 4, 0, 196, 81, 4, 0, 0, 16, 0, 52, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 74, \"data\": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 81, \"data\": [3, 70, 28, 0, 3, 2, 6], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 82, \"data\": [0, 0, 0, 0, 0, 0, 0, 5], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 84, \"data\": [3, 2, 7, 0, 81, 4, 1, 0, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 92, \"data\": [15, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 191, 3, 0, 0, 130, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 93, \"data\": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 94, \"data\": [24, 0, 48, 0, 0, 0, 2, 2, 33, 67, 77, 68, 33, 67, 77, 68, 33, 67, 77, 68, 33, 67, 77, 68, 0, 0, 2, 2, 33, 67, 77, 68, 33, 67, 77, 68, 33, 67, 77, 68, 33, 67, 77, 68, 0, 0, 2, 2, 33, 67, 77, 68, 33, 67, 77, 68, 33, 67, 77, 68, 33, 67, 77, 68], \"offset\": 0, \"address\": [255, 255, 255, 255]}, {\"rights\": 0, \"register\": 112, \"data\": [0, 0], \"offset\": 0, \"address\": [255, 255, 255, 255]}]}}", "devices use same config": true, "debug settings": {"adapter": "FTDI"}, "template properties": {"Mux Type": "USB3.x and DisplayPort", "Description": "TPS65982 Dual-Role Port, Power Agnostic, Prefers Data Source, supports HD3SS460 Mux:\n\nPower sink and source capabilities, will attempt to become the data source if possible. Supports USB3 and DisplayPort data paths using the external HD3SS460 Superspeed Mux from Texas Instruments. This is a good configuration for Laptop Computers that may be charged from a dock or power brick, but might also power an external device. It is easily modified to support power source only (with no sink capabilitiy) for externally-powered devices such as Desktop Computers\n", "Template Version": "4.03", "Port Type": "DRP", "Category Type": "Advanced Customer Project", "Device Type": "TPS65982", "Display As": "TPS65982 HD3SS460 DRP, Prefers Host", "Question List": [{"Answer": "TPS65982", "Question": "Which device are you using?"}, {"Answer": "Advanced", "Question": "Which template type do you want to start with?"}, {"Answer": "None", "Question": "Which Thunderbolt controller is used?"}, {"Answer": "Dual Role Port (DRP), prefers data host", "Question": "What is the port type of the design?"}]}}