Post Go back to editing

ADRV9029 DPD configuration.

Hi,

We are implementing DPD with ADRV9029. We have taken the configuration parameters for DPD from the python script  given below and implemented the same in c. The model file is taken form ADI Ezone. None for the API are getting failed and the error code in DPD status is also found to be 0 but we could see the configurations are not affecting. What can be issue ?

Is there any sample c code for DPD configuration ?

Thanks in advance.

#################################################################################
#GUI Version: 5.1.0.30
#DLL Version: 5.1.0.21
#Cmd Server Version: 5.1.0.21
#FPGA Version: 0xD9000007
#ARM Version: 5.1.0.9(ADI_ADRV9025_ARMBUILD_TESTOBJ)
#StreamVersion: 8.1.0.1
#################################################################################

#Import Reference to the DLL
import System
import clr
import time
from math import log10, sqrt
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

########################## HELPER FUNCTIONS #######################################

def dpdStatusGet(txChannel):
    print"***************************************"
    print "Retrieving DPD status"
    #dpdStatus = Types.adi_adrv9010_DpdStatus_t()
    dpdStatus = Types.adi_adrv9025_DpdStatusX_t()
    retVal = link.platform.board.Adrv9010Device.Dfe.DpdStatusGet(txChannel, dpdStatus)
    dpdStatus = retVal[1]
    print "dpdErrorCode:",dpdStatus.dpdErrorCode
    print "dpdPercentComplete",dpdStatus.dpdPercentComplete
    print "dpdPerformanceMetric",dpdStatus.dpdPerformanceMetric
    print "dpdIterCount",dpdStatus.dpdIterCount
    print "dpdUpdateCount",dpdStatus.dpdUpdateCount
    print "dpdSyncStatus",dpdStatus.dpdSyncStatus
    meanTu = dpdStatus.dpdStatistics.dpdMeanTuPower
    
    peakTu = dpdStatus.dpdStatistics.dpdPeakTuPower
    meanTx = dpdStatus.dpdStatistics.dpdMeanTxPower
    peakTx = dpdStatus.dpdStatistics.dpdPeakTxPower
    meanOrx = dpdStatus.dpdStatistics.dpdMeanOrxPower
    peakOrx = dpdStatus.dpdStatistics.dpdPeakOrxPower    
    
    print "dpdModelTable",dpdStatus.dpdModelTable
    if int(meanTu*10 + peakTu*10 + meanTx*10 + peakTx*10 + meanOrx*10 + peakOrx*10) != 0: 
        print "dpdMeanTuPower",20*log10(sqrt(meanTu) / 32768) 
        print "dpdPeakTuPower",20*log10(sqrt(peakTu) / 32768) 
        print "dpdMeanTxPower",20*log10(sqrt(meanTx) / 32768) 
        print "dpdPeakTxPower",20*log10(sqrt(peakTx) / 32768) 
        print "dpdMeanOrxPower",20*log10(sqrt(meanOrx) / 32768) 
        print "dpdPeakOrxPower",20*log10(sqrt(peakOrx) / 32768) 
    print "dpdDirectEvm",dpdStatus.dpdStatistics.dpdDirectEvm 
    print "dpdIndirectEvm",dpdStatus.dpdStatistics.dpdIndirectEvm 
    print "dpdSelectError",dpdStatus.dpdStatistics.dpdSelectError 
    print "dpdIndirectError",dpdStatus.dpdStatistics.dpdIndirectError 
    print "dpdErrorStatus0 (metrics:actions): X:X", dpdStatus.dpdErrorStatus0.dpdMetricsMask, dpdStatus.dpdErrorStatus0.dpdActionMask 
    print "dpdErrorStatus1 (metrics:actions): X:X", dpdStatus.dpdErrorStatus1.dpdMetricsMask, dpdStatus.dpdErrorStatus1.dpdActionMask 
    print "dpdPersistentErrorStatus0 (metrics:actions): X:X", dpdStatus.dpdPersistentErrorStatus0.dpdMetricsMask, dpdStatus.dpdPersistentErrorStatus0.dpdActionMask 
    print "dpdPersistentErrorStatus1 (metrics:actions): X:X", dpdStatus.dpdPersistentErrorStatus1.dpdMetricsMask, dpdStatus.dpdPersistentErrorStatus1.dpdActionMask 
    print "reservedPM",dpdStatus.reservedPM 
    print "reservedTP",dpdStatus.reservedTP 
    print "reservedPR",dpdStatus.reservedPR 
    print"***************************************"


def dpdTrackingConfigSet( txChMask = 0x1):
    print"***************************************"
    print"Setting up DPD Tracking Config"
    FULL_SCALE_CODE = 32768

    #Create a new instance of DPD tracking Config and read back values in the device
    dpdTrackCfg = Types.adi_adrv9025_DpdTrackingConfig_t()
    dpdTrackCfgGet = Types.adi_adrv9025_DpdTrackingConfig_t()
    retVal = link.platform.board.Adrv9010Device.Dfe.DpdTrackingConfigGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1,dpdTrackCfgGet)
    dpdTrackCfg = retVal[1]

    #Update DPD mode
    dpdTrackCfg.dpdUpdateMode =  Types.adi_adrv9010_DpdTrackingUpdateMode_e.ADI_ADRV9025_DPD_TRACKING_UPDATE_MODE_2

    #Update Peak search window and other params
    dpdTrackCfg.dpdPeakSearchWindowSize = 65535
    dpdTrackCfg.dpdIndirectRegularizationValue = 20
    dpdTrackCfg.dpdSamples = 16384
    dpdTrackCfg.dpdIndirectRegularizationLowPowerValue = 20
    dpdTrackCfg.dpdFilterSel = 1
    dpdTrackCfg.enableDirectLearning = 0
    dpdTrackCfg.dpdMu = 0

    #Update low power threshold
    DpdLowPowerThreshold_dBFS = -46
    dpdTrackCfg.minAvgSignalLevel = System.UInt16(pow(10,(DpdLowPowerThreshold_dBFS/20.0))*FULL_SCALE_CODE)

    #Update ORx low power threshold
    DpdLowPowerThresholdORx_dBFS = -36
    dpdTrackCfg.minAvgSignalLevelOrx = System.UInt16(pow(10,(DpdLowPowerThresholdORx_dBFS/20.0))*FULL_SCALE_CODE)

    #Convert M-Threshold in dBFS to linear scale
    MThreshold_dBFS = -40 
    temp = pow(10,(MThreshold_dBFS/20.0))*FULL_SCALE_CODE
    dpdTrackCfg.dpdMThreshold = pow(temp,2)
    
    #Program the values
    dpdTrackCfg.txChannelMask = txChMask
    link.platform.board.Adrv9010Device.Dfe.DpdTrackingConfigSet(dpdTrackCfg)

    #Read back the programmed values
    retVal = link.platform.board.Adrv9010Device.Dfe.DpdTrackingConfigGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1,dpdTrackCfgGet)
    dpdTrackCfg = retVal[1]
    print"DPD Tx Low Power Threshold(dBFS) = ",20*log10(dpdTrackCfg.minAvgSignalLevel/32768.0)
    print"DPD ORx Low Power Threshold(dBFS) = ",20*log10(dpdTrackCfg.minAvgSignalLevelOrx/32768.0)
    print"DPD M Threshold(dBFS) = ",20*log10(pow(dpdTrackCfg.dpdMThreshold,0.5)/32768.0)
    print"DPD Peak Search Window Size = ",dpdTrackCfg.dpdPeakSearchWindowSize
    print"DPD Regularization Value = ",dpdTrackCfg.dpdIndirectRegularizationValue
    print"DPD Samples = ",dpdTrackCfg.dpdSamples
    print"DPD Update Mode = ",dpdTrackCfg.dpdUpdateMode
    print " DPD Indirect Regularization Value LowPower", dpdTrackCfg.dpdIndirectRegularizationLowPowerValue
    print " dpdFilterSel", dpdTrackCfg.dpdFilterSel 
    print "enableDirectLearning", dpdTrackCfg.enableDirectLearning
    print "dpdMu", dpdTrackCfg.dpdMu
    print"***************************************"


DPD_MODEL_FILE = "C:\\Users\\pvalavan\\Desktop\\DFE\\DPD TESTING\\ADRV9025_4txDPD_TESTING\\DPD_Model\\Gen3_95coefficients.txt"

lut = Array.CreateInstance(Types.adi_adrv9010_DpdLut_e, 31)
lut[0] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT0
lut[1] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT1
lut[2] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT2
lut[3] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT3
lut[4] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT4
lut[5] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT5
lut[6] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT6
lut[7] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT7
lut[8] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT8
lut[9] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT9
lut[10] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT10
lut[11] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT11
lut[12] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT12
lut[13] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT13
lut[14] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT14
lut[15] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT15
lut[16] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT16
lut[17] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT17
lut[18] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT18
lut[19] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT19
lut[20] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT20
lut[21] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT21
lut[22] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT22
lut[23] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT23
lut[24] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT24
lut[25] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT25
lut[26] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT26
lut[27] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT27
lut[28] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT28
lut[29] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT29
lut[30] = Types.adi_adrv9010_DpdLut_e.ADI_ADRV9010_DPD_LUT30

def dpdModelRestoreFromFile(fileName = DPD_MODEL_FILE):    
    dpdModelRestore = Types.adi_adrv9025_DpdModelConfig_t();
    cnt = 0
    modelFile = open(fileName,'r')
    
    for line in modelFile:
        var = line.split()
        dpdModelRestore.dpdFeatures[cnt].i = System.Byte(var[0])
        dpdModelRestore.dpdFeatures[cnt].j = System.Byte(var[1])
        dpdModelRestore.dpdFeatures[cnt].k = System.Byte(var[2])
        dpdModelRestore.dpdFeatures[cnt].lut = lut[int(var[3])]
        dpdModelRestore.dpdFeatures[cnt].coeffReal = float(var[4])
        dpdModelRestore.dpdFeatures[cnt].coeffImaginary = float(var[5])
        cnt = cnt + 1
    modelFile.close

    print "Num coeffs read from file = ",cnt    

    dpdModelRestore.dpdNumFeatures = cnt
    dpdModelRestore.txChannelMask = 0x0F    
    
    link.platform.board.Adrv9010Device.Dfe.DpdModelConfigSet(dpdModelRestore)
    link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1, Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9025_DPD_LUT_RESTORE)
    link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX2, Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9025_DPD_LUT_RESTORE)
    link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX3, Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9025_DPD_LUT_RESTORE)
    link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX4, Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9025_DPD_LUT_RESTORE)

def resetDpdFull(TxChannel = 1):
    if TxChannel == 1:
        link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1,Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9010_DPD_RESET_FULL)
    if TxChannel == 2:
        link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX2,Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9010_DPD_RESET_FULL)
    if TxChannel == 3:
        link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX3,Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9010_DPD_RESET_FULL)
    if TxChannel == 4:
        link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX4,Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9010_DPD_RESET_FULL)


def runExtPathDelayInitCal(chMask):
    initCal = Types.adi_adrv9010_InitCals_t()
    initCal.calMask = int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_EXTERNAL_PATH_DELAY)
    initCal.channelMask = chMask
    initCal.warmBoot = 0

    print "calMask:", hex(initCal.calMask)
    link.platform.board.Adrv9010Device.Cals.InitCalsRun(initCal)
    print "Path delay cal blocking wait status:", link.platform.board.Adrv9010Device.Cals.InitCalsWait(3000, 0)[1]


def getExtPathDelay(txCh):

    extPathDelay = Types.adi_adrv9010_ExternalPathDelay_t()
    retVal = link.platform.board.Adrv9010Device.Cals.ExternalPathDelayGet(txCh, extPathDelay)
    extPathDelay = retVal[1]
    print "fifoDelay:",extPathDelay.fifoDelay
    print "interpolationIndex:", extPathDelay.interpolationIndex

def dpdTrackingCalEnable(enable = 1):
    print"***********************************"
    if(enable == 1):        
        print"Enabling DPD Tracking Cal"
        link.platform.board.Adrv9010Device.Cals.TrackingCalsEnableSet(int(Types.adi_adrv9010_TrackingCalibrations_e.ADI_ADRV9010_TRACK_TX1_DPD), Types.adi_adrv9010_TrackingCalEnableDisable_e.ADI_ADRV9010_TRACKING_CAL_ENABLE)
        link.platform.board.Adrv9010Device.Cals.TrackingCalsEnableSet(int(Types.adi_adrv9010_TrackingCalibrations_e.ADI_ADRV9010_TRACK_TX2_DPD), Types.adi_adrv9010_TrackingCalEnableDisable_e.ADI_ADRV9010_TRACKING_CAL_ENABLE)
        link.platform.board.Adrv9010Device.Cals.TrackingCalsEnableSet(int(Types.adi_adrv9010_TrackingCalibrations_e.ADI_ADRV9010_TRACK_TX3_DPD), Types.adi_adrv9010_TrackingCalEnableDisable_e.ADI_ADRV9010_TRACKING_CAL_ENABLE)
        link.platform.board.Adrv9010Device.Cals.TrackingCalsEnableSet(int(Types.adi_adrv9010_TrackingCalibrations_e.ADI_ADRV9010_TRACK_TX4_DPD), Types.adi_adrv9010_TrackingCalEnableDisable_e.ADI_ADRV9010_TRACKING_CAL_ENABLE)
    else:
        print"Disabling DPD Tracking Cal"
        link.platform.board.Adrv9010Device.Cals.TrackingCalsEnableSet(int(Types.adi_adrv9010_TrackingCalibrations_e.ADI_ADRV9010_TRACK_TX1_DPD), Types.adi_adrv9010_TrackingCalEnableDisable_e.ADI_ADRV9010_TRACKING_CAL_DISABLE)
        link.platform.board.Adrv9010Device.Cals.TrackingCalsEnableSet(int(Types.adi_adrv9010_TrackingCalibrations_e.ADI_ADRV9010_TRACK_TX2_DPD), Types.adi_adrv9010_TrackingCalEnableDisable_e.ADI_ADRV9010_TRACKING_CAL_DISABLE)
        link.platform.board.Adrv9010Device.Cals.TrackingCalsEnableSet(int(Types.adi_adrv9010_TrackingCalibrations_e.ADI_ADRV9010_TRACK_TX3_DPD), Types.adi_adrv9010_TrackingCalEnableDisable_e.ADI_ADRV9010_TRACKING_CAL_DISABLE)
        link.platform.board.Adrv9010Device.Cals.TrackingCalsEnableSet(int(Types.adi_adrv9010_TrackingCalibrations_e.ADI_ADRV9010_TRACK_TX4_DPD), Types.adi_adrv9010_TrackingCalEnableDisable_e.ADI_ADRV9010_TRACKING_CAL_DISABLE)
    print"***********************************"
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)

#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.10", 55556) 
    print "Connecting"

if (link.IsConnected()):
    adrv9010 = link.Adrv9010Get(1)
    print "Connected"
    ##### YOUR CODE GOES HERE #####
    
    dpdModelRestoreFromFile()
    resetDpdFull(1)
    dpdTrackingConfigSet()
    runExtPathDelayInitCal(0x1)# Should be 0XF for enabling path delay all four Tx channel #Run 1st after loading signal-> PA on -> Settign Tx atten and ORx gain index
    time.sleep(1)
    getExtPathDelay(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1) #Run 2nd to confirm extPathDelay ran fine

    
    dpdTrackingCalEnable(1) #Enable DPD tracking cal
    

    time.sleep(10)
    print "TX1"
    dpdStatusGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1) #Read back DPD Status
    '''
    print "TX2"
    dpdStatusGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX2) #Read back DPD Status
    print "TX3"
    dpdStatusGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX3) #Read back DPD Status
    print "TX4"
    dpdStatusGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX4) #Read back DPD Status
    '''
else:
    print "Not Connected"

if (connect):
    link.platform.board.Client.Disconnect()
    print "Disconnected"

  • Can you please make sure that you are executing the external path delay cal?

    def runExtPathDelayInitCal(chMask):
    initCal = Types.adi_adrv9010_InitCals_t()
    initCal.calMask = int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_EXTERNAL_PATH_DELAY)
    initCal.channelMask = chMask
    initCal.warmBoot = 0

    print "calMask:", hex(initCal.calMask)
    link.platform.board.Adrv9010Device.Cals.InitCalsRun(initCal)
    print "Path delay cal blocking wait status:", link.platform.board.Adrv9010Device.Cals.InitCalsWait(3000, 0)[1]

    Please make sure that you are executing the DpdReset with ADI_ADRV9025_DPD_LUT_RESTORE after executing DpdModelConfigSet().

    def dpdModelRestoreFromFile(fileName = DPD_MODEL_FILE):
    dpdModelRestore = Types.adi_adrv9025_DpdModelConfig_t();
    cnt = 0
    modelFile = open(fileName,'r')

    for line in modelFile:
    var = line.split()
    dpdModelRestore.dpdFeatures[cnt].i = System.Byte(var[0])
    dpdModelRestore.dpdFeatures[cnt].j = System.Byte(var[1])
    dpdModelRestore.dpdFeatures[cnt].k = System.Byte(var[2])
    dpdModelRestore.dpdFeatures[cnt].lut = lut[int(var[3])]
    dpdModelRestore.dpdFeatures[cnt].coeffReal = float(var[4])
    dpdModelRestore.dpdFeatures[cnt].coeffImaginary = float(var[5])
    cnt = cnt + 1
    modelFile.close

    print "Num coeffs read from file = ",cnt

    dpdModelRestore.dpdNumFeatures = cnt
    dpdModelRestore.txChannelMask = 0x0F

    link.platform.board.Adrv9010Device.Dfe.DpdModelConfigSet(dpdModelRestore)
    link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1, Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9025_DPD_LUT_RESTORE)
    link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX2, Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9025_DPD_LUT_RESTORE)
    link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX3, Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9025_DPD_LUT_RESTORE)
    link.platform.board.Adrv9010Device.Dfe.DpdReset(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX4, Types.adi_adrv9010_DpdResetMode_e.ADI_ADRV9025_DPD_LUT_RESTORE)

    Is there any sample c code for DPD configuration ?

    We don't have any sample "C" code.

  • Hi

    Thanks for your reply.

    We are executing all the APIs that you have mentioned in last post but still there is no change. Here I am attaching the main.c file where we have implemented DPD. Can you please help us finding where we are going wrong.

    This is the current DPD status and for dpdStatistics also all the values are found to be 0.

    /**
     * \file main.c
     * \brief Contains extern declarations for adrv9025 data structures initializations
     *
     * ADRV9025 API Version: 5.1.0.21
     */
    
    /**
     * Copyright 2015 - 2018 Analog Devices Inc.
     * Released under the ADRV9025 API license, for more information
     * see the "LICENSE.txt" file in this zip file.
     */
    
    #include <stdio.h>
    #include <unistd.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <string.h>
    #include <getopt.h>
    #include <math.h>
    
    #include "string.h"
    #include "adi_platform.h"
    #include "adi_adrv9025_daughter_board.h"
    #include "adi_adrv9025_utilities.h"
    #include "adi_adrv9025.h"
    #include "adi_adrv9025_radioctrl.h"
    #include "adi_adrv9025_tx.h"
    #include "adi_common_error.h"
    #include "adi_fpga9025.h"
    #include "adi_ad9528.h"
    #include "initdata.h"
    #include "platform_utils/adi_fmc_fru.h"
    #include "platform_utils/adi_fmc_eeprom.h"
    #include "daughterboards/adi_daughterboard_trx_types.h"
    #include "motherboards/adi_motherboard_trx.h"
    #include "adi_adrv9025_dfe_types.h"
    #include "adi_adrv9025_dfe.h"
    
    
    #define PROGNAME "adrv9029Init"
    #define PROGVERSION 1
    
    #define DPD_MODEL_FILENAME "Gen3_95coefficients.txt"
    
    void lws_enable_gpio();
    static void help(void);
    static void version(void);
    
    adi_motherboard_trx_t *motherboard = NULL;
    
    
    #if 0
    
    adi_adrv9025_DpdLut_e lut_var;
    unsigned int lut_t [31] = {0};
    //adi_adrv9025_DpdLut_e lut_t = {31};
    //adi_adrv9025_CfrCtrlConfig_t CfrCtrlConfig = {0};
    
    
    
    lut_t[0] = (int) ADI_ADRV9025_DPD_LUT0;
    lut_t[1] = ADI_ADRV9025_DPD_LUT1;
    lut_t[2] = ADI_ADRV9025_DPD_LUT2;
    lut_t[3] = ADI_ADRV9025_DPD_LUT3;
    lut_t[4] = ADI_ADRV9025_DPD_LUT4;
    lut_t[5] = ADI_ADRV9025_DPD_LUT5;
    lut_t[6] = ADI_ADRV9025_DPD_LUT6;
    lut_t[7] = ADI_ADRV9025_DPD_LUT7;
    lut_t[8] = ADI_ADRV9025_DPD_LUT8;
    lut_t[9] = ADI_ADRV9025_DPD_LUT9;
    lut_t[10] = ADI_ADRV9025_DPD_LUT10;
    lut_t[11] = ADI_ADRV9025_DPD_LUT11;
    lut_t[12] = ADI_ADRV9025_DPD_LUT12;
    lut_t[13] = ADI_ADRV9025_DPD_LUT13;
    lut_t[14] = ADI_ADRV9025_DPD_LUT14;
    lut_t[15] = ADI_ADRV9025_DPD_LUT15;
    lut_t[16] = ADI_ADRV9025_DPD_LUT16;
    lut_t[17] = ADI_ADRV9025_DPD_LUT17;
    lut_t[18] = ADI_ADRV9025_DPD_LUT18;
    lut_t[19] = ADI_ADRV9025_DPD_LUT19;
    lut_t[20] = ADI_ADRV9025_DPD_LUT20;
    lut_t[21] = ADI_ADRV9025_DPD_LUT21;
    lut_t[22] = ADI_ADRV9025_DPD_LUT22;
    lut_t[23] = ADI_ADRV9025_DPD_LUT23;
    lut_t[24] = ADI_ADRV9025_DPD_LUT24;
    lut_t[25] = ADI_ADRV9025_DPD_LUT25;
    lut_t[26] = ADI_ADRV9025_DPD_LUT26;
    lut_t[27] = ADI_ADRV9025_DPD_LUT27;
    lut_t[28] = ADI_ADRV9025_DPD_LUT28;
    lut_t[29] = ADI_ADRV9025_DPD_LUT29;
    lut_t[30] = ADI_ADRV9025_DPD_LUT30;
    
    #endif
    
    /* If Json file used for profile then set to 1
     * if structure initialization taken from "initdata.c" then set to 0*/
    #define USE_JSON_FILE 0
    static adi_fpga9025_Init_t fpga9025DeviceInitInst = { { { 0 } } };
    static adi_ad9528_Init_t ad9528InitInst = { { 0 } };
    adi_adrv9025_StreamSettings_t streamSettingsInst = { 0 };
    
    ///* Platfrom files settings */
    static adi_adrv9025_PlatformFiles_t platformFiles = { {"./resources/adrv9025/arm_firmware/ADRV9025_FW.bin;./resources/adrv9025/arm_firmware/ADRV9025_DPDCORE_FW.bin"},
    	{"./resources/adrv9025/arm_firmware/stream_image_A9A69F235992D2096E93E82C75508C29.bin"},
    	{ {{"./resources/adrv9025/gain_tables/RxGainTable.csv"}, 0xFF} },
    	1,
    	{ {{"./resources/adrv9025/gain_tables/TxAttenTable.csv"}, 0x0F} },
    	1};
    
    
    static int32_t adi_adrv9025_EnableTxExample (adi_adrv9025_Device_t *device)
    {
    	int32_t recoveryAction = 0;
    
    	if (device == NULL)
    	{
    		printf("NULL ADRV9025 device pointer\n");
    		return -1;
    	}
    	/* Setup internal Tx test tone frequency */
    	adi_adrv9025_TxTestToneCfg_t toneCfg = { 0 }; 
    	toneCfg.txChannelMask = ADI_ADRV9025_TXALL;
    	toneCfg.txToneFreq_Hz = 5000000;
    	toneCfg.txToneGain = ADI_ADRV9025_TX_NCO_0_DB;
    	toneCfg.enable = 1;
    
    	recoveryAction = adi_adrv9025_TxTestToneSet(device, &toneCfg, 1);
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to setup ADRV9025 Tx Test Tone\n");
    		printf("ERROR: Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				device->common.error.errCode,
    				device->common.error.newAction,
    				device->common.error.errFile,
    				device->common.error.errFunc,
    				device->common.error.errLine,
    				device->common.error.varName,
    				device->common.error.errormessage);
    		/* Call action handler */
    		return ADI_COMMON_ACT_ERR_RESET_FULL;
    	}
    	adi_adrv9025_TxAtten_t txAtten = { 0 };
    	txAtten.txChannelMask = ADI_ADRV9025_TXALL;
    	txAtten.txAttenuation_mdB = 25000; /* Back off Tx output power by 30dB */
    	recoveryAction = adi_adrv9025_TxAttenSet(device, &txAtten, 1);
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to set ADRV9025 Tx Attenuation\n");
    		printf("ERROR: Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				device->common.error.errCode,
    				device->common.error.newAction,
    				device->common.error.errFile,
    				device->common.error.errFunc,
    				device->common.error.errLine,
    				device->common.error.varName,
    				device->common.error.errormessage);
    		/* Call action handler */
    		return ADI_COMMON_ACT_ERR_RESET_FULL;
    	}
    
    	/* Enable Tx1 output : NOTE, make sure transmitter outputs are 50 ohm terminated or risk
    	 * possible damage to Tx output
    	 */
    	recoveryAction = adi_adrv9025_RxTxEnableSet(device, 0, ADI_ADRV9025_TXALL);
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to enable ADRV9025 Tx RF output\n");
    		printf("ERROR: Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				device->common.error.errCode,
    				device->common.error.newAction,
    				device->common.error.errFile,
    				device->common.error.errFunc,
    				device->common.error.errLine,
    				device->common.error.varName,
    				device->common.error.errormessage);
    		/* Call action handler */
    		return ADI_COMMON_ACT_ERR_RESET_FULL;
    	}
    
    	return 0;
    }
    
    void dpdModelRestoreFromFile (adi_adrv9025_Device_t *device )
    {
    	printf("Inside cfrCorrectionPulseLoadFromFile function\n");
    
    	adi_adrv9025_DpdModelConfig_t dpdModelRestore;
    	int32_t recoveryAction = 0;
    	FILE* fd;
    
    	fd = fopen (DPD_MODEL_FILENAME, "r");
    	if (fd == NULL )
    	{
    		printf("Can't DPD Model file name file\n");
    		fclose (fd);
    		exit(0);
    	}
    
    	int i = 0;                    	/*!< Memory term of the DPD feature */
    	int j = 0;                    	/*!< Cross term of the DPD feature */
    	int k = 0;                    	/*!< Power term of the DPD feature */
    	
    	//uint8_t i = 0;                    	/*!< Memory term of the DPD feature */
    	//uint8_t j = 0;                    	/*!< Cross term of the DPD feature */
    	//uint8_t k = 0;                    	/*!< Power term of the DPD feature */
    	int lutparam = 0;    		/*!< Target LUT index for this feature. Valid values are LUT0 - LUT30 */
    	float coeffReal = 0;              	/*!< Real part of the complex co-efficient for this feature */
    	float coeffImaginary = 0;
    
    	//int coeffReal = 0;              	/*!< Real part of the complex co-efficient for this feature */
    	//int coeffImaginary = 0;
    
    	int cnt = 0; 
    	while (!feof (fd))
    	//while (cnt < 95)
    	//while ( fscanf (fd, "%d %d %d %d %f %f", &i, &j, &k, &lutparam, &coeffReal, &coeffImaginary) == 6 )
    	{
    
    		fscanf (fd, "%d %d %d %d %f %f", &i, &j, &k, &lutparam, &coeffReal, &coeffImaginary);
    		printf("mode: %d %d %d %d %f %f\n",i, j, k, lutparam, coeffReal, coeffImaginary);
    
    		dpdModelRestore.dpdFeatures[cnt].i = i;
    		dpdModelRestore.dpdFeatures[cnt].j = j;
    		dpdModelRestore.dpdFeatures[cnt].k = k;
    		//dpdModelRestore.dpdFeatures[cnt].lut = lut_t[lutparam];
    		dpdModelRestore.dpdFeatures[cnt].lut = lutparam;
    		dpdModelRestore.dpdFeatures[cnt].coeffReal = coeffReal;
    		dpdModelRestore.dpdFeatures[cnt].coeffImaginary = coeffImaginary;
    		cnt = cnt + 1;
                    if (cnt == 95)
    			break;
    	}
    
    	fclose (fd);
    
    	printf("Num coeffs read from file = %d",cnt);
    	//cnt = 95;
    	dpdModelRestore.dpdNumFeatures = cnt;
    	dpdModelRestore.txChannelMask = 0x0F;
    
    	recoveryAction = adi_adrv9025_DpdModelConfigSet( device, &dpdModelRestore);
    
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to setup ADRV9025 CFR HARDCLIPPER\n");
    		printf("ERROR: Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				device->common.error.errCode,
    				device->common.error.newAction,
    				device->common.error.errFile,
    				device->common.error.errFunc,
    				device->common.error.errLine,
    				device->common.error.varName,
    				device->common.error.errormessage);
    		/* Call action handler */
    		//return ADI_COMMON_ACT_ERR_RESET_FULL;
    	}
    
    
    	adi_adrv9025_DpdReset(device, ADI_ADRV9025_TX1, ADI_ADRV9025_DPD_LUT_RESTORE);
    	adi_adrv9025_DpdReset(device, ADI_ADRV9025_TX2, ADI_ADRV9025_DPD_LUT_RESTORE);
    	adi_adrv9025_DpdReset(device, ADI_ADRV9025_TX3, ADI_ADRV9025_DPD_LUT_RESTORE);
    	adi_adrv9025_DpdReset(device, ADI_ADRV9025_TX4, ADI_ADRV9025_DPD_LUT_RESTORE);
    
    }
    
    void resetDpdFull(adi_adrv9025_Device_t *device, int TxChannel)
    {
    	if (TxChannel == 1)
    		adi_adrv9025_DpdReset(device, ADI_ADRV9025_TX1, ADI_ADRV9025_DPD_RESET_FULL);
    	if (TxChannel == 2)
    		adi_adrv9025_DpdReset(device, ADI_ADRV9025_TX2, ADI_ADRV9025_DPD_RESET_FULL);
    	if (TxChannel == 3)
    		adi_adrv9025_DpdReset(device, ADI_ADRV9025_TX3, ADI_ADRV9025_DPD_RESET_FULL);
    	if (TxChannel == 4)
    		adi_adrv9025_DpdReset(device, ADI_ADRV9025_TX4, ADI_ADRV9025_DPD_RESET_FULL);
    }
    
    void dpdTrackingConfigSet (adi_adrv9025_Device_t *device, uint32_t txChMask)
    {
    
    	printf("Setting up dpd tracking config\n");
    	printf("\n***************************************\n");
    
    	int32_t recoveryAction = 0;
    	int FULL_SCALE_CODE = 32768;
    
    	//Create a new instance of DPD tracking Config and read back values in the device
    	adi_adrv9025_DpdTrackingConfig_t dpdTrackCfg;
    	adi_adrv9025_DpdTrackingConfig_t dpdTrackCfgGet1;
    
    	adi_adrv9025_DpdTrackingConfigGet (device, ADI_ADRV9025_TX1, &dpdTrackCfgGet1);
    
    	//Update DPD mode
    
    	dpdTrackCfg.dpdUpdateMode =  ADI_ADRV9025_DPD_TRACKING_UPDATE_MODE_2;
    
    	//Update Peak search window and other params
    	dpdTrackCfg.dpdPeakSearchWindowSize = 65535; 
    	dpdTrackCfg.dpdIndirectRegularizationValue = 20;
    	dpdTrackCfg.dpdSamples = 16384;
    	dpdTrackCfg.dpdIndirectRegularizationLowPowerValue = 20;
    	dpdTrackCfg.dpdFilterSel = 1;
    	dpdTrackCfg.enableDirectLearning = 0;
    	dpdTrackCfg.dpdMu = 0;
    
    	//Update low power threshold
    	int DpdLowPowerThreshold_dBFS = -46;
    	dpdTrackCfg.minAvgSignalLevel = (uint16_t) ( (pow (10, (DpdLowPowerThreshold_dBFS/20.0) ) ) *FULL_SCALE_CODE);
    
    printf (" dpdTrackCfg.minAvgSignalLevel = %d\n",dpdTrackCfg.minAvgSignalLevel);
    	//Update ORx low power threshold 
    	int DpdLowPowerThresholdORx_dBFS = -36;
    	dpdTrackCfg.minAvgSignalLevelOrx = (uint16_t) ( (pow (10, (DpdLowPowerThresholdORx_dBFS/20.0) ) ) *FULL_SCALE_CODE);
    
    printf (" dpdTrackCfg.minAvgSignalLevelOrx = %d\n",dpdTrackCfg.minAvgSignalLevelOrx);
    
    	//Convert M-Threshold in dBFS to linear scale
    	int MThreshold_dBFS = -40;
    	int temp = pow(10,(MThreshold_dBFS/20.0))*FULL_SCALE_CODE;
    	dpdTrackCfg.dpdMThreshold = pow(temp,2);
    
    printf (" dpdTrackCfg.dpdMThreshold = %d\n",dpdTrackCfg.dpdMThreshold);
    	//Program the values
    	dpdTrackCfg.txChannelMask = txChMask;
    
    	recoveryAction = adi_adrv9025_DpdTrackingConfigSet(device, &dpdTrackCfg);
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to setup DpdTrackingConfigSet \n");
    		printf("ERROR: Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				device->common.error.errCode,
    				device->common.error.newAction,
    				device->common.error.errFile,
    				device->common.error.errFunc,
    				device->common.error.errLine,
    				device->common.error.varName,
    				device->common.error.errormessage);
    		/* Call action handler */
    		//return ADI_COMMON_ACT_ERR_RESET_FULL;
    	}
    
    
    	//Read back the programmed values
    	adi_adrv9025_DpdTrackingConfig_t dpdTrackCfgGet;
    	recoveryAction  = adi_adrv9025_DpdTrackingConfigGet(device, txChMask, &dpdTrackCfgGet);
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to setup DpdTrackingConfigSet \n");
    		printf("ERROR: Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				device->common.error.errCode,
    				device->common.error.newAction,
    				device->common.error.errFile,
    				device->common.error.errFunc,
    				device->common.error.errLine,
    				device->common.error.varName,
    				device->common.error.errormessage);
    		/* Call action handler */
    		//return ADI_COMMON_ACT_ERR_RESET_FULL;
    	}
    
    	//dpdTrackCfg = retVal[1];
    	printf("DPD Tx Low Power Threshold(dBFS) 		= %d\n",( 20 * ( log10(dpdTrackCfg.minAvgSignalLevel/32768.0) ) ) );
    	printf("DPD ORx Low Power Threshold(dBFS) 		= %d\n",( 20 * ( log10(dpdTrackCfg.minAvgSignalLevelOrx/32768.0) ) ) );
    	printf("DPD M Threshold(dBFS) 				= %d\n",( 20 * ( log10(pow(dpdTrackCfg.dpdMThreshold,0.5)/32768.0) ) ) );
    	printf("DPD Peak Search Window Size 			= %d\n",dpdTrackCfg.dpdPeakSearchWindowSize);
    	printf("DPD Regularization Value 			= %d\n",dpdTrackCfg.dpdIndirectRegularizationValue);
    	printf("DPD Samples 					= %d\n",dpdTrackCfg.dpdSamples);
    	printf("DPD Update Mode 				= %d\n",dpdTrackCfg.dpdUpdateMode);
    	printf("DPD Indirect Regularization Value LowPower 	= %d\n", dpdTrackCfg.dpdIndirectRegularizationLowPowerValue);
    	printf("dpdFilterSel 					= %d\n", dpdTrackCfg.dpdFilterSel);
    	printf("enableDirectLearning 				= %d\n", dpdTrackCfg.enableDirectLearning);
    	printf("dpdMu 						= %d\n", dpdTrackCfg.dpdMu);
    	printf("\n***************************************\n");
    
    
    	printf("DPD Tx Low Power Threshold(dBFS)                = %d\n", dpdTrackCfgGet.minAvgSignalLevel );
            printf("DPD ORx Low Power Threshold(dBFS)               = %d\n", dpdTrackCfgGet.minAvgSignalLevelOrx);
            printf("DPD M Threshold(dBFS)                           = %d\n", dpdTrackCfgGet.dpdMThreshold);
            printf("DPD Peak Search Window Size                     = %d\n", dpdTrackCfgGet.dpdPeakSearchWindowSize);
            printf("DPD Regularization Value                        = %d\n", dpdTrackCfgGet.dpdIndirectRegularizationValue);
            printf("DPD Samples                                     = %d\n", dpdTrackCfgGet.dpdSamples);
            printf("DPD Update Mode                                 = %d\n", dpdTrackCfgGet.dpdUpdateMode);
            printf("DPD Indirect Regularization Value LowPower      = %d\n", dpdTrackCfgGet.dpdIndirectRegularizationLowPowerValue);
            printf("dpdFilterSel                                    = %d\n", dpdTrackCfgGet.dpdFilterSel);
            printf("enableDirectLearning                            = %d\n", dpdTrackCfgGet.enableDirectLearning);
            printf("dpdMu                                           = %d\n", dpdTrackCfgGet.dpdMu);
            printf("\n***************************************\n");
    }
    
    
    
    
    void runExtPathDelayInitCal ( adi_adrv9025_Device_t *device, uint32_t chMask)
    {
    
    
    	int32_t recoveryAction = 0;
    	//adi_adrv9025_InitCals_t dpdcal        = {0};
    	adi_adrv9025_InitCals_t dpdcal ;
    	dpdcal.calMask     =  ADI_ADRV9025_EXTERNAL_PATH_DELAY;
    	dpdcal.channelMask = chMask;
    	dpdcal.warmBoot    = 0;
    	recoveryAction = adi_adrv9025_InitCalsRun (device, &dpdcal);
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to setup ADRV9025 dpd Run Init cals\n");
    		printf("ERROR: Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				device->common.error.errCode,
    				device->common.error.newAction,
    				device->common.error.errFile,
    				device->common.error.errFunc,
    				device->common.error.errLine,
    				device->common.error.varName,
    				device->common.error.errormessage);
    		/* Call action handler */
    		//return ADI_COMMON_ACT_ERR_RESET_FULL;
    	}
    	uint8_t errFlags;
    	recoveryAction = adi_adrv9025_InitCalsWait (device, 3000, &errFlags);
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to setup ADRV9025 dpd wait init cals \n");
    		printf("ERROR: Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				device->common.error.errCode,
    				device->common.error.newAction,
    				device->common.error.errFile,
    				device->common.error.errFunc,
    				device->common.error.errLine,
    				device->common.error.varName,
    				device->common.error.errormessage);
    		/* Call action handler */
    		//return ADI_COMMON_ACT_ERR_RESET_FULL;
    	}
    
    }
    
    
    void getExtPathDelay (adi_adrv9025_Device_t *device, uint32_t txCh)
    {
    	int32_t recoveryAction = 0;
    	adi_adrv9025_ExternalPathDelay_t extPathDelay;
    	recoveryAction = adi_adrv9025_ExternalPathDelayGet (device, txCh, &extPathDelay);
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to getExtPathDelay\n");
    		printf("ERROR: Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				device->common.error.errCode,
    				device->common.error.newAction,
    				device->common.error.errFile,
    				device->common.error.errFunc,
    				device->common.error.errLine,
    				device->common.error.varName,
    				device->common.error.errormessage);
    		/* Call action handler */
    		//return ADI_COMMON_ACT_ERR_RESET_FULL;
    	}
    
    	printf ("fifoDelay		:%d\n",extPathDelay.fifoDelay);
    	printf ("interpolationIndex	:%d\n", extPathDelay.interpolationIndex);
    }
    
    void dpdTrackingCalEnable (adi_adrv9025_Device_t *device, int enable )
    
    {
    	printf("***********************************\n");
    	if(enable == 1){
    		printf("Enabling DPD Tracking Cal\n");
    		adi_adrv9025_TrackingCalsEnableSet (device, ADI_ADRV9025_TRACK_TX1_DPD, ADI_ADRV9025_TRACKING_CAL_ENABLE);
    		adi_adrv9025_TrackingCalsEnableSet (device, ADI_ADRV9025_TRACK_TX2_DPD, ADI_ADRV9025_TRACKING_CAL_ENABLE);
    		adi_adrv9025_TrackingCalsEnableSet (device, ADI_ADRV9025_TRACK_TX3_DPD, ADI_ADRV9025_TRACKING_CAL_ENABLE);
    		adi_adrv9025_TrackingCalsEnableSet (device, ADI_ADRV9025_TRACK_TX4_DPD, ADI_ADRV9025_TRACKING_CAL_ENABLE);
    	}    
    	else{
    		printf("Disabling DPD Tracking Cal\n");
    		adi_adrv9025_TrackingCalsEnableSet (device, ADI_ADRV9025_TRACK_TX1_DPD, ADI_ADRV9025_TRACKING_CAL_DISABLE);
    		adi_adrv9025_TrackingCalsEnableSet (device, ADI_ADRV9025_TRACK_TX2_DPD, ADI_ADRV9025_TRACKING_CAL_DISABLE);
    		adi_adrv9025_TrackingCalsEnableSet (device, ADI_ADRV9025_TRACK_TX3_DPD, ADI_ADRV9025_TRACKING_CAL_DISABLE);
    		adi_adrv9025_TrackingCalsEnableSet (device, ADI_ADRV9025_TRACK_TX4_DPD, ADI_ADRV9025_TRACKING_CAL_DISABLE);
    	}
    	printf("***********************************");
    }
    
    
    void dpdStatusGet( adi_adrv9025_Device_t *device, uint32_t  txChannel)
    {
    	printf("***************************************\n");
    	printf ("Retrieving DPD status\n");
    	//dpdStatus = Types.adi_adrv9010_DpdStatus_t()
    	//dpdStatus = Types.adi_adrv9025_DpdStatusX_t()
    	adi_adrv9025_DpdStatus_t dpdStatus;
    	int32_t recoveryAction = 0;
    	recoveryAction = adi_adrv9025_DpdStatusGet (device, txChannel, &dpdStatus);
    
    	printf ("dpdErrorCode		:0x%x\n",dpdStatus.dpdErrorCode);
    	printf ("dpdPercentComplete	:%d\n",dpdStatus.dpdPercentComplete);
    	printf ("dpdPerformanceMetric	:%d\n",dpdStatus.dpdPerformanceMetric);
    	printf ("dpdIterCount		:%d\n",dpdStatus.dpdIterCount);
    	printf ("dpdUpdateCount		:%d\n",dpdStatus.dpdUpdateCount);
    	printf ("dpdSyncStatus		:%d\n",dpdStatus.dpdSyncStatus);
    
    	float meanTu = dpdStatus.dpdStatistics.dpdMeanTuPower;
    	float peakTu = dpdStatus.dpdStatistics.dpdPeakTuPower;
    	float meanTx = dpdStatus.dpdStatistics.dpdMeanTxPower;
    	float peakTx = dpdStatus.dpdStatistics.dpdPeakTxPower;
    	float meanOrx = dpdStatus.dpdStatistics.dpdMeanOrxPower;
    	float peakOrx = dpdStatus.dpdStatistics.dpdPeakOrxPower;
    
    	printf ("dpdModelTable		:%d\n",dpdStatus.dpdModelTable);
    
    	if (((int)(meanTu*10 + peakTu*10 + meanTx*10 + peakTx*10 + meanOrx*10 + peakOrx*10)) != 0)
    	{
    		printf ("dpdMeanTuPower		:%f\n",20*log10(sqrt(meanTu) / 32768));
    		printf ("dpdPeakTuPower		:%f\n",(20*log10(sqrt(peakTu) / 32768)));
    		printf ("dpdMeanTxPower		:%f\n",(20*log10(sqrt(meanTx) / 32768)));
    		printf ("dpdPeakTxPower		:%f\n",20*log10(sqrt(peakTx) / 32768));
    		printf ("dpdMeanOrxPower		:%f\n",20*log10(sqrt(meanOrx) / 32768));
    		printf ("dpdPeakOrxPower		:%f\n",20*log10(sqrt(peakOrx) / 32768));
    		printf ("dpdDirectEvm		:%f\n",dpdStatus.dpdStatistics.dpdDirectEvm);
    		printf ("dpdIndirectEvm		:%f\n",dpdStatus.dpdStatistics.dpdIndirectEvm);
    		printf ("dpdSelectError		:%f\n",dpdStatus.dpdStatistics.dpdSelectError);
    		printf ("dpdIndirectError	:%f\n",dpdStatus.dpdStatistics.dpdIndirectError);
    		printf ("dpdErrorStatus0 (metrics:actions): X:X	:%d:%d\n",	dpdStatus.dpdErrorStatus0.dpdMetricsMask, 
    										dpdStatus.dpdErrorStatus0.dpdActionMask);
    
    		printf ("dpdErrorStatus1 (metrics:actions)		:%d:%d\n", 	dpdStatus.dpdErrorStatus1.dpdMetricsMask, 
    											dpdStatus.dpdErrorStatus1.dpdActionMask);
    		printf ("dpdPersistentErrorStatus0 (metrics:actions)	:%d:%d\n", 	dpdStatus.dpdPersistentErrorStatus0.dpdMetricsMask, 
    											dpdStatus.dpdPersistentErrorStatus0.dpdActionMask);
    		printf ("dpdPersistentErrorStatus1 (metrics:actions)	:%d:%d\n", 	dpdStatus.dpdPersistentErrorStatus1.dpdMetricsMask, 
    											dpdStatus.dpdPersistentErrorStatus1.dpdActionMask);
    		printf ("reservedPM		:%d\n",dpdStatus.reservedPM);
    		printf ("reservedTP		:%d\n",dpdStatus.reservedTP);
    		printf ("reservedPR		:%d\n",dpdStatus.reservedPR);
    		printf ("***************************************\n");
    	}
    }
    
    
    #define dpdInitMain main
    int dpdInitMain()
    
    {
    
    	int c;
    	int32_t recoveryAction = 0;
    	adi_adrv9025_Device_t *device = NULL;
    	adi_fpga9025_Device_t *fpga9025Device = NULL;
    	adi_ad9528_Device_t *ad9528Device = NULL;
    
    	// Discover board and platform.
    	recoveryAction = adi_motherboard_Discover(&motherboard);
    	if ((recoveryAction != ADI_COMMON_HAL_OK) || (motherboard == NULL))
    	{
    		printf("ERROR: adi_Motherboard_Discover has failed.\n");
    		return ADI_COMMON_ACT_ERR_RESET_FULL;
    	}
    
    	lws_enable_gpio();
    
    	// Discover daughterboard.
    	recoveryAction = adi_daughterboard_Discover(motherboard);
    	if ((recoveryAction != ADI_COMMON_HAL_OK) || (motherboard == NULL))
    	{
    		printf("ERROR: ERPC-SERVER: %s:%u has failed.\n", __func__, __LINE__);
    		return (-1);
    	}
    
    	recoveryAction = adi_motherboard_SaveInfo(motherboard, (uintptr_t)&adrv9025InitInst, TRX_PLATFORM_DATA_SAVE_TRX_SETTING_INIT);
    	if (recoveryAction != ADI_COMMON_HAL_OK)
    	{
    		printf("ERROR: CMD-SERVER: %s:%u has failed.\n", __func__, __LINE__);
    		return (-1);
    	}
    
    	recoveryAction = adi_motherboard_SaveInfo(motherboard, (uintptr_t)&adrv9025PostMcsInitInst, TRX_PLATFORM_DATA_SAVE_TRX_SETTING_POST_MCS);
    	if (recoveryAction != ADI_COMMON_HAL_OK)
    	{
    		printf("ERROR: CMD-SERVER: %s:%u has failed.\n", __func__, __LINE__);
    		return (-1);
    	}
    
    	recoveryAction = adi_motherboard_SaveInfo(motherboard, (uintptr_t)&ad9528InitInst, TRX_PLATFORM_DATA_SAVE_CLOCK_SETTING_INIT);
    	if (recoveryAction != ADI_COMMON_HAL_OK)
    	{
    		printf("ERROR: CMD-SERVER: %s:%u has failed.\n", __func__, __LINE__);
    		return (-1);
    	}
    
    	recoveryAction = adi_motherboard_SaveInfo(motherboard, (uintptr_t)&fpga9025DeviceInitInst, TRX_PLATFORM_DATA_SAVE_FPGA_SETTING_INIT);
    	if (recoveryAction != ADI_COMMON_HAL_OK)
    	{
    		printf("ERROR: CMD-SERVER: %s:%u has failed.\n", __func__, __LINE__);
    		return (-1);
    	}
    
    	recoveryAction = adi_motherboard_SaveInfo(motherboard, (uintptr_t)&platformFiles, TRX_PLATFORM_DATA_SAVE_TRX_SETTING_PLATFORM_FILES);
    	if (recoveryAction != ADI_COMMON_HAL_OK)
    	{
    		printf("ERROR: CMD-SERVER: %s:%u has failed.\n", __func__, __LINE__);
    		return (-1);
    	}
    
    	recoveryAction = adi_motherboard_SaveInfo(motherboard, (uintptr_t)&streamSettingsInst, TRX_PLATFORM_DATA_SAVE_STREAM_SETTING_INIT);
    	if (recoveryAction != ADI_COMMON_HAL_OK)
    	{
    		printf("ERROR: CMD-SERVER: %s:%u has failed.\n", __func__, __LINE__);
    		return (-1);
    	}
    
    	device = (adi_adrv9025_Device_t *) motherboard->daughterboards[0]->trxDevice;
    	//fpga9025Device = (adi_fpga9025_Device_t*) motherboard->daughterboards[0]->fpgaDevice;
    	ad9528Device = (adi_ad9528_Device_t *) motherboard->daughterboards[0]->clockDevice;
    
    	device->common.error.logEnable = 1;
    	//fpga9025Device->memoryPageSize = 0x10000000;
    
    #if 0
    	if (USE_JSON_FILE)
    	{
    		if ((recoveryAction = adi_adrv9025_ConfigFileLoad(device, "/home/analog/adrv9025_c_example/resources/adrv9025/profiles/public/ADRV9025Init_StdUseCase13_nonLinkSharing.profile", &adrv9025InitInst)) != ADI_COMMON_ACT_NO_ACTION)
    		{
    			printf("Error loading the requested profile to ADRV9025 init");
    			printf("ERROR: Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    					device->common.error.errCode,
    					device->common.error.newAction,
    					device->common.error.errFile,
    					device->common.error.errFunc,
    					device->common.error.errLine,
    					device->common.error.varName,
    					device->common.error.errormessage);
    			/* Call action handler */
    			return ADI_COMMON_ACT_ERR_RESET_FULL;
    		}
    	}
    	else
    	{
    		/* ADRV9025 settings are used from initdata.c 
    		 * they are already loaded in adrv9025InitInst.
    		 * Verify that the structure was generated for the same API */
    
    		adi_adrv9025_ApiVersion_t apiVersion;
    		recoveryAction = adi_adrv9025_ApiVersionGet(device, &apiVersion);
    		if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    		{
    			printf("ERROR: adi_adrv9025_ApiVersionGet has failed.\n");
    			return ADI_COMMON_ACT_ERR_RESET_FULL;
    		}
    
    		if (initStructApiVersion.majorVer != apiVersion.majorVer || initStructApiVersion.minorVer != apiVersion.minorVer || initStructApiVersion.maintenanceVer != apiVersion.maintenanceVer || initStructApiVersion.buildVer != apiVersion.buildVer)
    		{
    			printf("ERROR: Device initialization structure in \"initdata.c\" was generated for API version %d.%d.%d.%d, but the detected version on the device is %d.%d.%d.%d.\n\n",
    					initStructApiVersion.majorVer, initStructApiVersion.minorVer, initStructApiVersion.maintenanceVer, initStructApiVersion.buildVer,
    					apiVersion.majorVer, apiVersion.minorVer, apiVersion.maintenanceVer, apiVersion.buildVer);
    			return ADI_COMMON_ACT_ERR_RESET_FULL;
    		}
    	}
    
    	/* Init Ad9528 */
    	recoveryAction = motherboard->daughterboards[0]->ClockConfigure(
    			//ToDo:        motherboard->daughterboards[0], (uintptr_t)&ad9528InitInst, adrv9010InitInst.clocks.deviceClock_kHz, 122880, 122880, adrv9010InitInst.clocks.deviceClock_kHz);
    		motherboard->daughterboards[0], 
    		(uintptr_t) &ad9528InitInst,  
    		245760,
    		122880,
    		30720,
    		245760);
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		return recoveryAction;
    	}
    
    #endif
    	/*
    	 * Function will Program the devices
    	 */
    	recoveryAction = motherboard->daughterboards[0]->BoardProgram(motherboard->daughterboards[0]);
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to initialize ADRV9025 Board\n");
    		printf("ERROR: ADRV9025 Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				device->common.error.errCode,
    				device->common.error.newAction,
    				device->common.error.errFile,
    				device->common.error.errFunc,
    				device->common.error.errLine,
    				device->common.error.varName,
    				device->common.error.errormessage);
    		printf("ERROR: fpga9025Device Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				fpga9025Device->common.error.errCode,
    				fpga9025Device->common.error.newAction,
    				fpga9025Device->common.error.errFile,
    				fpga9025Device->common.error.errFunc,
    				fpga9025Device->common.error.errLine,
    				fpga9025Device->common.error.varName,
    				fpga9025Device->common.error.errormessage);
    		printf("ERROR: ad9528Device Error number %d, Recovery action %d. In file %s, in function %s, in line %d, variable name %s. Error message %s.\n",
    				ad9528Device->common.error.errCode,
    				ad9528Device->common.error.newAction,
    				ad9528Device->common.error.errFile,
    				ad9528Device->common.error.errFunc,
    				ad9528Device->common.error.errLine,
    				ad9528Device->common.error.varName,
    				ad9528Device->common.error.errormessage);
    		/* Call action handler */
    		return recoveryAction;
    	}
    
    	printf("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    
    	printf("Configuring DPD model restore from file\n");
    
    	dpdModelRestoreFromFile (device);
    
    
    	printf("Resetting DPD full\n");
    
    	resetDpdFull (device, 1);
    
    	printf("Programming DPD tracking config set\n");
    
    	dpdTrackingConfigSet (device, ADI_ADRV9025_TX1);
    
    	/*Should be 0XF for enabling path delay all four Tx channel 
    #Run 1st after loading signal-> PA on -> Settign Tx atten and ORx gain index */
    	printf("Programming runExtPathDelayInitCal \n");
    
    	runExtPathDelayInitCal (device, 1);
    
    	printf("Programming getExtPathDelay \n");
    
    	getExtPathDelay (device, ADI_ADRV9025_TX1); //Run 2nd to confirm extPathDelay ran fine
    
    	printf("Programming dpdTrackingCalEnable\n");
    
    	dpdTrackingCalEnable (device, 1); //Enable DPD tracking cal
    
    	printf("Programming dpdStatusGet\n");
    
    	printf ("TX1\n");
    	dpdStatusGet (device, ADI_ADRV9025_TX1); //Read back DPD Status
    #if 0
    	printf ("TX2\n");
    	dpdStatusGet (ADRV9025_TX2); //Read back DPD Status
    	printf ("TX3\n");
    	dpdStatusGet(ADRV9025_TX3); //Read back DPD Status
    	printf ("TX4\n");
    	dpdStatusGet(ADRV9025_TX4); //Read back DPD Status
    #endif 
    
    	recoveryAction = motherboard->Destroy(motherboard);
    	motherboard = NULL;
    
    	if (recoveryAction != ADI_COMMON_ACT_NO_ACTION)
    	{
    		printf("Failed to destroy motherboard and daughterboard\n");
    		/* Call action handler */
    	}
    	printf("ADRV9026 initialized successfully\n");
    	return recoveryAction;
    }
    

  • Are you using pin control mode or API mode enabling/disabling Tx channel?

    Can you please readback and check whether the Tx path is enabled are not?

    adi_adrv9025_RxTxEnableGet()

    If Tx channels are not enabled try enabling the Tx channels using 

    adi_adrv9025_RxTxEnableSet()

    Readback the ORX Channel enabled/disabled using

     adi_adrv9025_RxTxEnableGet()

    If ORX channels are enabled, disable all ORX channel using adi_adrv9025_RxTxEnableSet().

    After enabling DPD, when you transmit baseband signal are you able to see ADRV9025 Tx output in spectrum analyzer? Can you please share Tx output spectrum?

    What is the power level input of ORX?

    Can you please read the power of ORX with adi_adrv9025_RxDecPowerGet()?

    If above steps are not helping, Please share the full log for the ADRV9025 with log level set to 255.

  • Hi

    Thanks for your quick response.

    We are having separate individual scripts for initialisation of ADRV9029, CFR and DPD. And our sequence of initialisation is as below.

    1 - Initialising ADRV9029 and transmitting base band signal.

    2- Initialising CFR.

    3- Initialising DPD.

    We are using API mode to enable tx path and all the tx and rx channels are enabled. We are not enabling ORX channels. Here I am attaching the adi_adrv9025_RxTxEnableGet() status. I have attached the log files as well.


    After Initialising ADRV9029 and transmitting baseband signal, Tx output image:

    After initialising DPD Tx output image:

    What is the power level input of ORX?

    It is -22.168 dBm.                         

    5488.logs.tar.gz

  • Are you still reading the DPD statistics as zero?

    Are you able to read back the DPDConfigGet and DPD Model file correctly?

    One thing i could see from your "DPD C" code is that after enabling the DPD tracking cal, you are directly reading the DPD status. Can you please add some delay (few sec) and try?

    Please refer below delay numbers from python script,

    dpdTrackingCalEnable(1) #Enable DPD tracking cal

    time.sleep(10)
    print "TX1"
    dpdStatusGet(Types.adi_adrv9010_TxChannels_e.ADI_ADRV9010_TX1) #Read back DPD Status

    Also i could see few CFR related instance in the code, Please check.

    printf("Inside cfrCorrectionPulseLoadFromFile function\n");
    printf("Failed to setup ADRV9025 CFR HARDCLIPPER\n");

  • Are you still reading the DPD statistics as zero?

    Yes Still I am reading the DPD statistics as 0.

    Are you able to read back the DPDConfigGet and DPD Model file correctly?

    Yes I am able to read back the DPDConfigGet and DPD model file correctly.

    Tried adding delay of 10 sec after dpdTrackingCalEnable but it did not help.

    Also i could see few CFR related instance in the code, Please check.

    Please ignore this as these are some prints mistake. 

    If ORX channels are enabled, disable all ORX channel using adi_adrv9025_RxTxEnableSet().

    In the previous post you have asked to disable the ORX . Are you sure we should disable ORX channels while testing DPD ? Or there is some kind of confusion. Can you please clarify on the same because I can adi_adrv9025_RxDecPowerGet() is getting failed saying error message as below

    Thanks !

  • In the previous post you have asked to disable the ORX . Are you sure we should disable ORX channels while testing DPD ? Or there is some kind of confusion. Can you please clarify on the same because I can adi_adrv9025_RxDecPowerGet() is getting failed saying error message as below

    While testing DPD we recommend to disable the ORX Path. Before enabling DPD you can enable ORX path and measure ORXDecpower if required.

    While DPD tracking cal is executing the DPD status will be reporting the ORX power. User need not to try measuring ORX power using adi_adrv9025_RxDecPowerGet().

    Are you able to Run Ext_LoL init calibration?.

    I hope you are using TX1 and ORX1 channels in your custom board.

    Can you please read back and share the adi_adrv9025_TxToOrxMappingGet() API response?

    Are you seeing this issue on all Tx channels?