Post Go back to editing

DPD fail

Category: Software
Product Number: ADRV9029
Software Version: 6.0.0.41

Hello:

    What can we do when DPD failed,sometimes the dpdErrorCode was 0x341D or 0x340C or 0x340A,  then the ACLR performance was very bad. 

    I see the DPD robustness chapter in user guide, can it  recover the dpd error?

    How can I use the function when dpd mode is ADI_ADRV9025_DPD_MODE2

Best regards!

  • Please follow the below link on troubleshooting the DPD errors.

    https://wiki.analog.com/resources/eval/user-guides/adrv9029/dpd_error_troubleshooting

    Below are the DPD errors that are shown as part of API Source package as well.

    What can we do when DPD failed,sometimes the dpdErrorCode was 0x341D or 0x340C or 0x340A,  then the ACLR performance was very bad. 

    We need to find out the reason why these errors are being triggered before relying on relaxing the Default condition threshold settings.

    Please share the DPD statistics for better understanding of the issue.

  • Hi Ramarao:

    The DPD status read back as follow screen when the system run one night. The dpdIterCount was 17356, the dpdupdateCount was 2648,  and the dpdupdateCount was stopped now, 

    another  why the recovery action which reset DPD adaptation and hardware reset was not done when the dpdErrorStatus0_dpdMetricsMask was 0x380,  the dpdPersistentErrorStatus0_dpdMetricsMask was 0x300?

    The Fault Conditions were:

  • The DPD status read back as follow screen when the system run one night. The dpdIterCount was 17356, the dpdupdateCount was 2648,  and the dpdupdateCount was stopped now, 

    We need to find out why the update count is so less when compared with the Iteration count. Which DPD Update mode are you using?

    Also, from the DPD statistics, there is stability error which means the DPD update will not happen. 

    For recovery action we typically recommend to OR the different recovery actions. Please see the attached reference python script.

    #################################################################################
    #GUI Version: 0.0.0.939
    #DLL Version: 0.0.0.857
    #Cmd Server Version: 0.0.0.857
    #FPGA Version: 0xD9000007
    #ARM Version: 0.0.0.503
    #StreamVersion: 0.0.0.73
    #Author: Anand Kumar
    #Precondition: Ensure that the DPD tracking cal is disabled before running this script
    #Description: This script sets up the DPD robustness framework, and reads back the metrics and action mask after setting up the DPD 
    # Specifically, the DPD LUT updates are skipped if indirect error is greater than 5%
    # If the direct EVM is persistently greater than 5% for at least 10 update periods, the DPD is reset.
    #################################################################################
    
    #Import Reference to the DLL
    import System
    import clr
    import time
    from System import Array
    clr.AddReferenceToFileAndPath("C:\\Program Files\\Analog Devices\\ADRV9025 Transceiver Evaluation Software_x64_FULL\\adrvtrx_dll.dll")
    from adrv9010_dll import AdiEvaluationSystem
    from adrv9010_dll import Types
    from adrv9010_dll import Ad9528Types
    
    def spiRead(address):
        data = adrv9010.Hal.SpiByteRead(address, 0)
        print "SPI Read Address " + hex(address) + ": " + hex(data[1])
    
    def spiWrite(address, data):
        adrv9010.Hal.SpiByteWrite(address, data)
        print "SPI Write Address " + hex(address) + ": " + hex(data)
    
    def dpdStabilityCondnSetup(txChannelMask = 0xF):
        DEFAULT_WARNING_PERCENTAGE = 10
        DEFAULT_ERROR_PERCENTAGE = 15
        DEFAULT_WARNING_dBFS = -36
        DEFAULT_ERROR_dBFS = -40  
        ERROR_PERSISTENT_COUNT = 10
    	
        dpdFaultConditionArr = Array.CreateInstance(Types.adi_adrv9010_DpdFaultCondition_t, 10)
        dpdFaultConditionArr[0] = Types.adi_adrv9010_DpdFaultCondition_t()
        dpdFaultConditionArr[0].dpdMetric = Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_INDIRECT_EVM
        dpdFaultConditionArr[0].comparator = Types.adi_adrv9010_DpdComparator_e.ADI_ADRV9010_DPD_COMPARATOR_GREATER_THAN
        dpdFaultConditionArr[0].threshold0 = (DEFAULT_WARNING_PERCENTAGE)
        dpdFaultConditionArr[0].threshold1 = (DEFAULT_ERROR_PERCENTAGE)
        dpdFaultConditionArr[0].persistentCount = ERROR_PERSISTENT_COUNT
    
        dpdFaultConditionArr[1] = Types.adi_adrv9010_DpdFaultCondition_t()
        dpdFaultConditionArr[1].dpdMetric = Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_DIRECT_EVM
        dpdFaultConditionArr[1].comparator = Types.adi_adrv9010_DpdComparator_e.ADI_ADRV9010_DPD_COMPARATOR_GREATER_THAN
        dpdFaultConditionArr[1].threshold0 = (DEFAULT_WARNING_PERCENTAGE)
        dpdFaultConditionArr[1].threshold1 = (DEFAULT_ERROR_PERCENTAGE)
        dpdFaultConditionArr[1].persistentCount = ERROR_PERSISTENT_COUNT
    
        dpdFaultConditionArr[2] = Types.adi_adrv9010_DpdFaultCondition_t()
        dpdFaultConditionArr[2].dpdMetric = Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_SELECT_ERROR
        dpdFaultConditionArr[2].comparator = Types.adi_adrv9010_DpdComparator_e.ADI_ADRV9010_DPD_COMPARATOR_GREATER_THAN
        dpdFaultConditionArr[2].threshold0 = (DEFAULT_WARNING_PERCENTAGE)
        dpdFaultConditionArr[2].threshold1 = (DEFAULT_ERROR_PERCENTAGE)
        dpdFaultConditionArr[2].persistentCount = ERROR_PERSISTENT_COUNT
    
        dpdFaultConditionArr[3] = Types.adi_adrv9010_DpdFaultCondition_t()
        dpdFaultConditionArr[3].dpdMetric = Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_INDIRECT_ERROR
        dpdFaultConditionArr[3].comparator = Types.adi_adrv9010_DpdComparator_e.ADI_ADRV9010_DPD_COMPARATOR_GREATER_THAN
        dpdFaultConditionArr[3].threshold0 = (DEFAULT_WARNING_PERCENTAGE)
        dpdFaultConditionArr[3].threshold1 = (DEFAULT_ERROR_PERCENTAGE)
        dpdFaultConditionArr[3].persistentCount = ERROR_PERSISTENT_COUNT
    
        dpdFaultConditionArr[4] = Types.adi_adrv9010_DpdFaultCondition_t()
        dpdFaultConditionArr[4].dpdMetric = Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_MEAN_TU_POWER
        dpdFaultConditionArr[4].comparator = Types.adi_adrv9010_DpdComparator_e.ADI_ADRV9010_DPD_COMPARATOR_LESS_THAN
        dpdFaultConditionArr[4].threshold0 = (-25 * 100)
        dpdFaultConditionArr[4].threshold1 = (-40 * 100)
        dpdFaultConditionArr[4].persistentCount = ERROR_PERSISTENT_COUNT
    
        dpdFaultConditionArr[5] = Types.adi_adrv9010_DpdFaultCondition_t()
        dpdFaultConditionArr[5].dpdMetric = Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_PEAK_TU_POWER
        dpdFaultConditionArr[5].comparator = Types.adi_adrv9010_DpdComparator_e.ADI_ADRV9010_DPD_COMPARATOR_LESS_THAN
        dpdFaultConditionArr[5].threshold0 = (DEFAULT_WARNING_dBFS * 100)
        dpdFaultConditionArr[5].threshold1 = (DEFAULT_ERROR_dBFS * 100)
        dpdFaultConditionArr[5].persistentCount = ERROR_PERSISTENT_COUNT
    
        dpdFaultConditionArr[6] = Types.adi_adrv9010_DpdFaultCondition_t()
        dpdFaultConditionArr[6].dpdMetric = Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_PEAK_TX_POWER
        dpdFaultConditionArr[6].comparator = Types.adi_adrv9010_DpdComparator_e.ADI_ADRV9010_DPD_COMPARATOR_LESS_THAN
        dpdFaultConditionArr[6].threshold0 = (DEFAULT_WARNING_dBFS * 100)
        dpdFaultConditionArr[6].threshold1 = (DEFAULT_ERROR_dBFS * 100)
        dpdFaultConditionArr[6].persistentCount = ERROR_PERSISTENT_COUNT
    
        dpdFaultConditionArr[7] = Types.adi_adrv9010_DpdFaultCondition_t()
        dpdFaultConditionArr[7].dpdMetric = Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_MEAN_TX_POWER
        dpdFaultConditionArr[7].comparator = Types.adi_adrv9010_DpdComparator_e.ADI_ADRV9010_DPD_COMPARATOR_LESS_THAN
        dpdFaultConditionArr[7].threshold0 = (DEFAULT_WARNING_dBFS * 100)
        dpdFaultConditionArr[7].threshold1 = (DEFAULT_ERROR_dBFS * 100)
        dpdFaultConditionArr[7].persistentCount = ERROR_PERSISTENT_COUNT
    
        dpdFaultConditionArr[8] = Types.adi_adrv9010_DpdFaultCondition_t()
        dpdFaultConditionArr[8].dpdMetric = Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_PEAK_ORX_POWER
        dpdFaultConditionArr[8].comparator = Types.adi_adrv9010_DpdComparator_e.ADI_ADRV9010_DPD_COMPARATOR_LESS_THAN
        dpdFaultConditionArr[8].threshold0 = (DEFAULT_WARNING_dBFS * 100)
        dpdFaultConditionArr[8].threshold1 = (DEFAULT_ERROR_dBFS * 100)
        dpdFaultConditionArr[8].persistentCount = ERROR_PERSISTENT_COUNT
    
        dpdFaultConditionArr[9] = Types.adi_adrv9010_DpdFaultCondition_t()
        dpdFaultConditionArr[9].dpdMetric = Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_MEAN_ORX_POWER
        dpdFaultConditionArr[9].comparator = Types.adi_adrv9010_DpdComparator_e.ADI_ADRV9010_DPD_COMPARATOR_LESS_THAN
        dpdFaultConditionArr[9].threshold0 = (DEFAULT_WARNING_dBFS * 100)
        dpdFaultConditionArr[9].threshold1 = (DEFAULT_ERROR_dBFS * 100)
        dpdFaultConditionArr[9].persistentCount = ERROR_PERSISTENT_COUNT
    
        link.platform.board.Adrv9010Device.Dfe.DpdFaultConditionSet(txChannelMask, dpdFaultConditionArr, 10)
    
    def dpdRecoveryActionConfigSet(txChannelMask = 0x0F):
        print"***************************************"
        print"Setting up Recovery Actions for DPD Robustness"   
        
        #Setup Recovery Action
        dpdRecoveryActionArr = Array.CreateInstance(Types.adi_adrv9010_DpdRecoveryActionConfig_t, 4)   
    
        #Configure Recovery Action for violation of threshold0
        dpdRecoveryActionArr[0] = Types.adi_adrv9010_DpdRecoveryActionConfig_t()
        dpdRecoveryActionArr[0].dpdErrorState = Types.adi_adrv9010_DpdErrorState_e.ADI_ADRV9010_DPD_ERR_STATE_0
        dpdRecoveryActionArr[0].dpdRecoveryAction.dpdMetricsMask = int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_DIRECT_EVM)
        dpdRecoveryActionArr[0].dpdRecoveryAction.dpdMetricsMask |= int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_INDIRECT_ERROR)
        dpdRecoveryActionArr[0].dpdRecoveryAction.dpdMetricsMask |= int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_SELECT_ERROR)
        dpdRecoveryActionArr[0].dpdRecoveryAction.dpdMetricsMask |= int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_MEAN_TU_POWER)
        dpdRecoveryActionArr[0].dpdRecoveryAction.dpdActionMask = int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_SKIP_LUTS_UPDATE)
    
        #Configure Recovery Action for violation of threshold1
        dpdRecoveryActionArr[1] = Types.adi_adrv9010_DpdRecoveryActionConfig_t()
        dpdRecoveryActionArr[1].dpdErrorState = Types.adi_adrv9010_DpdErrorState_e.ADI_ADRV9010_DPD_ERR_STATE_1
        dpdRecoveryActionArr[1].dpdRecoveryAction.dpdMetricsMask = int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_DIRECT_EVM)
        dpdRecoveryActionArr[1].dpdRecoveryAction.dpdMetricsMask |= int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_INDIRECT_ERROR)
        dpdRecoveryActionArr[1].dpdRecoveryAction.dpdActionMask = 0#int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_SKIP_LUTS_UPDATE)
    
        #Configure Recovery Action for persistent violation of threshold0
        thresh0ActionMaskPersistent = 0
        thresh0ActionMaskPersistent |= int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_SKIP_LUTS_UPDATE)
        thresh0ActionMaskPersistent |= int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_RESET_FIRST_DPD_FLAG)
        thresh0ActionMaskPersistent |= int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_REVERT_LUTS_TO_UNITY)
        thresh0ActionMaskPersistent |= int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_RESET_ADAPTATION_STATE)
    	
        dpdRecoveryActionArr[2] = Types.adi_adrv9010_DpdRecoveryActionConfig_t()
        dpdRecoveryActionArr[2].dpdErrorState = Types.adi_adrv9010_DpdErrorState_e.ADI_ADRV9010_DPD_ERR_STATE_PERSISTENT_0
        dpdRecoveryActionArr[2].dpdRecoveryAction.dpdMetricsMask = int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_DIRECT_EVM)
        dpdRecoveryActionArr[2].dpdRecoveryAction.dpdMetricsMask |= int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_INDIRECT_ERROR)
        dpdRecoveryActionArr[2].dpdRecoveryAction.dpdMetricsMask |= int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_SELECT_ERROR)
        dpdRecoveryActionArr[2].dpdRecoveryAction.dpdActionMask = thresh0ActionMaskPersistent
    
        #Configure Recovery Action for persistent violation of threshold1
        thresh1ActionMaskPersistent = 0
        thresh1ActionMaskPersistent |= int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_SKIP_LUTS_UPDATE)
        thresh1ActionMaskPersistent |= int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_REVERT_LUTS_TO_UNITY)
        thresh1ActionMaskPersistent |= int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_RESET_ADAPTATION_STATE) 
        thresh1ActionMaskPersistent |= int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_RESET_FIRST_DPD_FLAG) 
        thresh1ActionMaskPersistent |= int(Types.adi_adrv9010_DpdRecoveryAction_e.ADI_ADRV9010_DPD_RECOVERY_ACTION_6DB_DIG_ATTEN)	
    
        dpdRecoveryActionArr[3] = Types.adi_adrv9010_DpdRecoveryActionConfig_t()
        dpdRecoveryActionArr[3].dpdErrorState = Types.adi_adrv9010_DpdErrorState_e.ADI_ADRV9010_DPD_ERR_STATE_PERSISTENT_1
        dpdRecoveryActionArr[3].dpdRecoveryAction.dpdMetricsMask = int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_DIRECT_EVM)
        dpdRecoveryActionArr[3].dpdRecoveryAction.dpdMetricsMask |= int(Types.adi_adrv9010_DpdMetric_e.ADI_ADRV9010_DPD_METRIC_INDIRECT_ERROR)
        dpdRecoveryActionArr[3].dpdRecoveryAction.dpdActionMask = 0#thresh1ActionMaskPersistent    
    
        #Program the recovery action in the device
        link.platform.board.Adrv9010Device.Dfe.DpdRecoveryActionSet(txChannelMask, dpdRecoveryActionArr, 4)
        print"***************************************"
    
    def dpdRecoveryActionConfigGet():
        print"***************************************"
        print"Reading back Recovery Actions for DPD Robustness"  
        dpdRecoveryActionFromDevice = Types.adi_adrv9010_DpdRecoveryActionConfig_t()
        [recAction, dpdRecoveryActionFromDevice] = link.platform.board.Adrv9010Device.Dfe.DpdRecoveryActionGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1, Types.adi_adrv9010_DpdErrorState_e.ADI_ADRV9010_DPD_ERR_STATE_0, dpdRecoveryActionFromDevice)
        print "Recovery Action - Metrics Mask Error State 0 =",dpdRecoveryActionFromDevice.dpdRecoveryAction.dpdMetricsMask
        print "Recovery Action - Action Mask Error State 0 =",dpdRecoveryActionFromDevice.dpdRecoveryAction.dpdActionMask
        print " "
    
        dpdRecoveryActionFromDevice = Types.adi_adrv9010_DpdRecoveryActionConfig_t()
        [recAction, dpdRecoveryActionFromDevice] = link.platform.board.Adrv9010Device.Dfe.DpdRecoveryActionGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1, Types.adi_adrv9010_DpdErrorState_e.ADI_ADRV9010_DPD_ERR_STATE_1, dpdRecoveryActionFromDevice)
        print "Recovery Action - Metrics Mask Error State 1 =",dpdRecoveryActionFromDevice.dpdRecoveryAction.dpdMetricsMask
        print "Recovery Action - Action Mask Error State 1 =",dpdRecoveryActionFromDevice.dpdRecoveryAction.dpdActionMask
        print " "
    
        dpdRecoveryActionFromDevice = Types.adi_adrv9010_DpdRecoveryActionConfig_t()
        [recAction, dpdRecoveryActionFromDevice] = link.platform.board.Adrv9010Device.Dfe.DpdRecoveryActionGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1, Types.adi_adrv9010_DpdErrorState_e.ADI_ADRV9010_DPD_ERR_STATE_PERSISTENT_0, dpdRecoveryActionFromDevice)
        print "Recovery Action - Metrics Mask Persistent 0 =",dpdRecoveryActionFromDevice.dpdRecoveryAction.dpdMetricsMask
        print "Recovery Action - Action Mask Persistent 0 =",dpdRecoveryActionFromDevice.dpdRecoveryAction.dpdActionMask
        print " "
    
        dpdRecoveryActionFromDevice = Types.adi_adrv9010_DpdRecoveryActionConfig_t()
        [recAction, dpdRecoveryActionFromDevice] = link.platform.board.Adrv9010Device.Dfe.DpdRecoveryActionGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1, Types.adi_adrv9010_DpdErrorState_e.ADI_ADRV9010_DPD_ERR_STATE_PERSISTENT_1, dpdRecoveryActionFromDevice)
        print "Recovery Action - Metrics Mask Persistent 1 =",dpdRecoveryActionFromDevice.dpdRecoveryAction.dpdMetricsMask
        print "Recovery Action - Action Mask Persistent 1 =",dpdRecoveryActionFromDevice.dpdRecoveryAction.dpdActionMask
        print " "
    
    #Create an Instance of the Class
    link = AdiEvaluationSystem.Instance	
    connect = False
    
    if (link.IsConnected() == False):
        connect = True
        link.platform.board.Client.Connect("192.168.1.145", 55556) 
        print "Connecting"
    
    if (link.IsConnected()):
        adrv9010 = link.Adrv9010Get(1)
        print "Connected"
        ##### YOUR CODE GOES HERE #####
        dpdStabilityCondnSetup()
        dpdRecoveryActionConfigSet()
        dpdRecoveryActionConfigGet()
        print "DPD Recovery Actions Configuration Complete"
    else:
        print "Not Connected"
    
    if (connect):
        link.platform.board.Client.Disconnect()
        print "Disconnected"

  • Hi Ramarao:

    The DpdUpdateMode is 2,I have used the recovery action script, it worked normal. thanks.

    I want to know how to calculate the dpdMThreshold and minAvgSignalLevel that were configured in API adi_adrv9025_DpdTrackingConfigSet.

    Best regards!

  • M-Threshold is to set the Max-power threshold. In DPD update Mode 2, you would have 2 Tables, one is C-Table which is used for Low power and another one is M-Table which is for high power. More details in the UG.

    You need to run a small test to exactly know the M-threshold.

    Could you please let us know the reason for using Update Mode 2? Are you using GaN or your signal varies dynamically, if so using Mode 2 is fine otherwise we would suggest to use Mode 0.

    minAvgsignal level is the signal level above which the DPD will start operating. If the capturesd signal level is below this threshold, the DPD would be in unity gain mode/ DPD in Bypass mode.

  • Thanks for your guidance about M-Threshold.

    I want to figure out how to calculate number:1044914=-21dBFs for dpdMThreshold, number 519 equal to -36dBFs for minAvgSignalLevel?

    The system use GaN PA and the signal varies dynamically. The dpdMode was set 0 defore, but dpd worked unstabilized, so we try to use Mode 2, it works better now. 

    Best regards!

  • I hope i have provided all the details on your queries and you are not waiting for any more inputs. Thanks.

  • Hi Ramarao:

    Can you tell me the calculation formula of dpdMThreshold,  Is 1044914 for -21dBFs?

  • NO, thats not correct.

    -21dBFS in linear value will be 8529034. Please see below for the calculations. Full scale code is 32768 here.