Post Go back to editing

How to config DPD on AD9375?

Thread Summary

The user is experiencing issues with DPD performance on a custom board using AD9375 with a GaN PA, where the system with DPD enabled runs slower and has higher error rates compared to without DPD. The DPD and CLGC configurations appear correct, but the CLGC error status indicates it is disabled due to `allowTx1AttenUpdates` and `allowTx2AttenUpdates` being set incorrectly. The user is advised to ensure these parameters are enabled and to measure EVM and Tx output power to diagnose the issue further.
AI Generated Content

Hi,

I use default DPDconfig to configure DPD on my custom board:

static mykonosDpdConfig_t dpdConfig =
{
    10,              /* 1/2^(damping + 8) fraction of power `forgotten' per sample (default: `1/8192' = 5, valid 0 to 15), 0 = infinite damping*/
    1,              /* number of weights to use for int8_cpx weights weights member of this structure (default = 1)*/
    2,              /* DPD model version: one of four different generalized polynomial models: 0 = same as R0 silicon, 1-3 are new and the best one depends on the PA (default: 2)*/
    1,              /* 1 = Update saved model whenever peak Tx digital RMS is within 1dB of historical peak Tx RMS*/
    20,             /* Determines how much weight the loaded prior model has on DPD modeling (Valid 0 - 32, default 20)*/
    0,              /* Default off = 0, 1=enables automatic outlier removal during DPD modeling */
    512,            /* Number of samples to capture (default: 512, valid 64-32768)*/
    4096,           /* threshold for sample in AM-AM plot outside of 1:1 line to be thrown out. (default: 50% = 8192/2, valid 8192 to 1)*/
    0,              /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
    255,            /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191)*/
    {{64,0},{0,0},{0,0}}/* DPD model error weighting (real/imag valid from -128 to 127)*/
};

My system have multi mode BPSK, QPSK, QUAM16,QUAM64 with bandwidth 5MHz, 10MHz, 20Mhz. 

I have feedback Tx2 signal into ORX2 with power -24dbm and configure dpd follow ug992. But i don't see any different between have setup DPD and no have DPD.

Here is status that I read using MYKONOS_getDpdStatus:

 dpdStatus.dpdErrorStatus = 0,

dpdStatus.dpdExtPathDelay = 0x73B ,

dpdStatus.dpdIterCount = 0,

dpdStatus.dpdMaxAdaptation = 0,

dpdStatus.dpdModelErrorPercent = 1000,

dpdStatus.dpdTrackCount = 0

Can you suggest for me how to solve? Thanks. This is my output from tx:

Edit Notes

dpdStatus.dpdErrorStatus = 0, dpdStatus.dpdExtPathDelay = 0x73B , dpdStatus.dpdIterCount = 0, dpdStatus.dpdMaxAdaptation = 0, dpdStatus.dpdModelErrorPercent = 1000, dpdStatus.dpdTrackCount = 0
[edited by: sonminh at 2:00 AM (GMT 0) on 24 Apr 2020]

Thread Notes

Parents
  • HI ,

    I have mistake once post this question in to that forum, then I received this answer:

    "Moving to No-Os forum for comments on the DPD configuration"

    Because I don't know delete that question, I have post again in this forum.

    Thanks

  • Without Tx output EVM plot with DPD its hard to say.

    If you reduce the Tx power by 3 dB how is the performance with DPD ? 

  • Hi, In above test cases, I get status of mykonosVswrStatus and mykonosClgcStatus. I see both errorStatus and  trackCount return 0. Why trackCount = 0( Number of times clgc and vswr has successfull run since initialization calibration = 0)
    )?. Is it affect to successfull of DPD?

  • CLGC and VSWR do not impact DPD. They are seperate cal. 

    Your DPD iteration count is increasing , so set up required for DPD is correct. May be there is something wrong with CLGC configuration.

  • Hi ,

    In page 4 of ad9375 datasheet, specification of image rejection at 5500Mhz is 50dbm. But once I try with 3 tone signal 3Mhz, 6Mhz, 9Mhz on AD9375, It generate 3 image -3Mhz, -6Mhz, -9Mhz. and not pass specification.

    How to decrease or filter 3 above image signal. How to configure AD9375 to decrease image signal?

  • Can you share screenshot of your measurement. Are you running QEC tracking calibration.?

    With single tone , what is the level of image?

    What is your application ? If its 4G/5G can you test with a 4G signal at offset and measure QEC performance with tracking cals enabled? 

  • Thanks

     I implement Calib DPD with:

    trackingCalMask = TRACK_ORX1_QEC | TRACK_ORX2_QEC | TRACK_RX1_QEC |
                                 TRACK_RX2_QEC | TRACK_TX1_QEC | TRACK_TX2_QEC | TRACK_TX1_LOL | TRACK_TX2_LOL;


     initCalMaskDpd =  TX_LO_LEAKAGE_EXTERNAL | DPD_INIT | CLGC_INIT | VSWR_INIT;

    You say :"Your DPD iteration count is increasing , so set up required for DPD is correct. May be there is something wrong with CLGC configuration"

    Maybe CLGC configuration not correct because I read  status of CLGC :

    Both clgcStatus.errorStatus and  clgcStatus.trackCount return 0x00;

    I configure Clgc by api:


        mykError = MYKONOS_configClgc(&mykDevice);
        if (mykError != MYKONOS_ERR_OK) {
            errorString = getMykonosErrorMessage(mykError);
    //        goto error_11;
        }
     and clgcConfig default:

    static mykonosClgcConfig_t clgcConfig =
    {
        -2000,          /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx1 output to ORx1 input in (dB * 100)*/
        -2000,          /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx2 output to ORx2 input in (dB * 100)*/
        0,              /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx1Atten is not reduced below the limit*/
        0,              /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx2Atten is not reduced below the limit*/
        75,             /* valid range 1-100, default 75*/
        75,             /* valid range 1-100, default 45*/
        0,              /* 0= allow CLGC to run, but Tx1Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx1Atten automatically updated*/
        0,              /* 0= allow CLGC to run, but Tx2Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx2Atten automatically updated*/
        0,              /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
        255,            /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191)*/
        600,            /* Threshold for Tx1 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/
        600,            /* Threshold for Tx2 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/
        0,              /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/
        0               /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/
    };

    How to configure to run success CLGC ?

  • Your CLGC config looks fine.

    Can you please share your complete sequence? (Including CLGC init and tracking)

  • Thanks  for your reply.

    When change frequency,I run DPD and CLGC calibration follow this sequence:

    	/*************************************************************************/
    	/*****            Enable DPD calibrations                            *****/
    	/*************************************************************************/
    	uint8_t				errorFlag = 0;
    	uint8_t				errorCode = 0;
    	uint32_t			initCalsCompleted;
    
    
    	uint32_t trackingCalMask = TRACK_ORX1_QEC | TRACK_ORX2_QEC | TRACK_RX1_QEC |
    							 TRACK_RX2_QEC | TRACK_TX1_QEC | TRACK_TX2_QEC | TRACK_TX1_LOL | TRACK_TX2_LOL;
    
    	uint32_t initCalMaskDpd =  TX_LO_LEAKAGE_EXTERNAL | DPD_INIT | CLGC_INIT | VSWR_INIT;
    
    
    
    	if ((mykError = MYKONOS_radioOff(&mykDevice)) != MYKONOS_ERR_OK)
    	{
    		/*** < Info: errorString will contain log error string in order to debug why radioOn failed > ***/
    		//errorString = getMykonosErrorMessage(mykError);
    		puts(getMykonosErrorMessage(mykError));
    
    	}
    
    	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, TX_PLL, u64TxFrq)) != MYKONOS_ERR_OK) {
    		return MYKONOS_ERR_FAILED;
    	}
    	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, RX_PLL, u64RxFrq)) != MYKONOS_ERR_OK)
    	{
    		return MYKONOS_ERR_FAILED;
    	}
    	Delay_Ms(100);
    
    
    	// Make sure PA is ON
    	if((mykError = MYKONOS_abortInitCals(&mykDevice, &initCalsCompleted)) != MYKONOS_ERR_OK)
    	{
    		/*** < Info: errorString will contain log error string in order to debug why failed > ***/
    		//errorString = getMykonosErrorMessage(mykError);
    		puts("abortInitCals failed");
    		fflush(stdout);
    		puts(getMykonosErrorMessage(mykError));
    	}
    
    	LREP("\r\n Mykonos ARM Initialization Calibrations for DPD");
    
    	if ((mykError = MYKONOS_runInitCals(&mykDevice, initCalMaskDpd)) != MYKONOS_ERR_OK)
    	{
    		/*** < Info: errorString will contain log error string in order to debug why failed > ***/
    		//errorString = getMykonosErrorMessage(mykError);
    		puts("MYKONOS_runInitCals");
    		fflush(stdout);
    		puts(getMykonosErrorMessage(mykError));
    
    	}
    
    	if ((mykError = MYKONOS_waitInitCals(&mykDevice, 60000, &errorFlag, &errorCode)) != MYKONOS_ERR_OK)
    	{
    		/*** < Info: errorString will contain log error string in order to debug why failed > ***/
    		//errorString = getMykonosErrorMessage(mykError);
    		puts("MYKONOS_waitInitCals");
    		fflush(stdout);
    		puts(getMykonosErrorMessage(mykError));
    	 }
    
    	if ((mykError = MYKONOS_getEnabledTrackingCals(&mykDevice, &trackingCalMask)) != MYKONOS_ERR_OK)
    	{
    		/*** < Info: errorString will contain log error string in order to debug why failed > ***/
    		//errorString = getMykonosErrorMessage(mykError);
    		puts("MYKONOS_getEnabledTrackingCals");
    		fflush(stdout);
    		puts(getMykonosErrorMessage(mykError));
    	}
    
    	trackingCalMask |= TRACK_TX1_DPD | TRACK_TX2_DPD | TRACK_TX1_CLGC | TRACK_TX2_CLGC | TRACK_TX1_VSWR | TRACK_TX2_VSWR;
    
    	if ((mykError = MYKONOS_enableTrackingCals(&mykDevice, trackingCalMask)) != MYKONOS_ERR_OK)
    	{
    		/*** < Info: errorString will contain log error string in order to debug why enableTrackingCals failed > ***/
    		//errorString = getMykonosErrorMessage(mykError);
    		puts(getMykonosErrorMessage(mykError));
    	}
    
    
    	MYKONOS_radioOn(&mykDevice);
    
    	/*** < Info: Allow TxQEC to run when User: is not actively using ORx receive path > ***/
    	if ((mykError = MYKONOS_setObsRxPathSource(&mykDevice, OBS_RXOFF)) != MYKONOS_ERR_OK)
    	{
    		/*** < Info: errorString will contain log error string in order to debug why setObsRxPathSource failed > ***/
    		//errorString = getMykonosErrorMessage(mykError);
    		puts(getMykonosErrorMessage(mykError));
    
    	}
    	if ((mykError = MYKONOS_setObsRxPathSource(&mykDevice, OBS_INTERNALCALS)) != MYKONOS_ERR_OK)
    	{
    		/*** < Info: errorString will contain log error string in order to debug why setObsRxPathSource failed > ***/
    		//errorString = getMykonosErrorMessage(mykError);
    		puts(getMykonosErrorMessage(mykError));
    
    	}
    
    	return MYKONOS_ERR_OK;

  • What is the Tx attenuation you are using to set the target power with CLGC? You should not use 0 dB attenuation, as CLGC need some headroom to track the target power by changing the Tx Attenuation.

    Can you please print the complete status of CLGC?

    typedef struct
    {
    uint32_t errorStatus;
    uint32_t trackCount;
    int32_t desiredGain;
    int32_t currentGain;
    uint32_t txGain;
    int32_t txRms;
    int32_t orxRms;
    } mykonosClgcStatus_t;

    You shall test CLGC by varying the ORX attenuation and see whether the Target power is maintained or not.

    Please refer to the below post for reference,

    https://ez.analog.com/wide-band-rf-transceivers/design-support-ad9371/f/q-a/163838/ad9357-clgc-custom-configuration-parameters

  • Thanks ,

    Sorry, I have mistake when get CLGC status.

     I veryfied CLGCStatus again every 1s. It return in order
    clgcStatus.errorStatus, clgcStatus.trackCount, clgcStatus.desiredGain, clgcStatus.currentGain, clgcStatus.txGain, clgcStatus.txRms, clgcStatus.orxRms

    CLGCStatus: 9 27 -2000 -809 40 -1662 -2472
    CLGCStatus: 9 29 -2000 -820 40 -1671 -2492
    CLGCStatus: 9 30 -2000 -857 40 -1685 -2543
    CLGCStatus: 9 32 -2000 -812 40 -1669 -2481
    CLGCStatus: 9 34 -2000 -843 40 -1677 -2520
    CLGCStatus: 9 35 -2000 -829 40 -1678 -2508
    CLGCStatus: 9 38 -2000 -902 40 -1710 -2612
    CLGCStatus: 9 43 -2000 -825 40 -1639 -2465
    CLGCStatus: 9 45 -2000 -854 40 -1689 -2543
    CLGCStatus: 9 47 -2000 -854 40 -1668 -2523

    I check errorStatus = 9. Thats means: "

    CLGC feature is disabled. This error is displayed when allowTx1AttenUpdates/
    allowTx2AttenUpdates are disabled


    "

    But in clgcConfig, i had enabled allowTx1AttenUpdates/allowTx2AttenUpdates

    static mykonosClgcConfig_t clgcConfig =
    {
        -2000,          /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx1 output to ORx1 input in (dB * 100)*/
        -2000,          /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx2 output to ORx2 input in (dB * 100)*/
        0,              /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx1Atten is not reduced below the limit*/
        0,              /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx2Atten is not reduced below the limit*/
        75,             /* valid range 1-100, default 75*/
        75,             /* valid range 1-100, default 45*/
        1,              /* 0= allow CLGC to run, but Tx1Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx1Atten automatically updated*/
        1,              /* 0= allow CLGC to run, but Tx2Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx2Atten automatically updated*/
        0,              /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
        255,            /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191)*/
        600,            /* Threshold for Tx1 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/
        600,            /* Threshold for Tx2 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/
        0,              /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/
        0               /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/
    };

    Can you give solution?

    Thanks

Reply
  • Thanks ,

    Sorry, I have mistake when get CLGC status.

     I veryfied CLGCStatus again every 1s. It return in order
    clgcStatus.errorStatus, clgcStatus.trackCount, clgcStatus.desiredGain, clgcStatus.currentGain, clgcStatus.txGain, clgcStatus.txRms, clgcStatus.orxRms

    CLGCStatus: 9 27 -2000 -809 40 -1662 -2472
    CLGCStatus: 9 29 -2000 -820 40 -1671 -2492
    CLGCStatus: 9 30 -2000 -857 40 -1685 -2543
    CLGCStatus: 9 32 -2000 -812 40 -1669 -2481
    CLGCStatus: 9 34 -2000 -843 40 -1677 -2520
    CLGCStatus: 9 35 -2000 -829 40 -1678 -2508
    CLGCStatus: 9 38 -2000 -902 40 -1710 -2612
    CLGCStatus: 9 43 -2000 -825 40 -1639 -2465
    CLGCStatus: 9 45 -2000 -854 40 -1689 -2543
    CLGCStatus: 9 47 -2000 -854 40 -1668 -2523

    I check errorStatus = 9. Thats means: "

    CLGC feature is disabled. This error is displayed when allowTx1AttenUpdates/
    allowTx2AttenUpdates are disabled


    "

    But in clgcConfig, i had enabled allowTx1AttenUpdates/allowTx2AttenUpdates

    static mykonosClgcConfig_t clgcConfig =
    {
        -2000,          /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx1 output to ORx1 input in (dB * 100)*/
        -2000,          /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx2 output to ORx2 input in (dB * 100)*/
        0,              /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx1Atten is not reduced below the limit*/
        0,              /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx2Atten is not reduced below the limit*/
        75,             /* valid range 1-100, default 75*/
        75,             /* valid range 1-100, default 45*/
        1,              /* 0= allow CLGC to run, but Tx1Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx1Atten automatically updated*/
        1,              /* 0= allow CLGC to run, but Tx2Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx2Atten automatically updated*/
        0,              /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/
        255,            /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191)*/
        600,            /* Threshold for Tx1 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/
        600,            /* Threshold for Tx2 in order to stop tracking, value = 100 * dB, default 6db then value = 600*/
        0,              /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/
        0               /* Threshold feature enable for Tx1, 0 = disable, 1 = enable, default = 0*/
    };

    Can you give solution?

    Thanks

Children