Post Go back to editing

How to config DPD on AD9375?

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:



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]
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

  • Can you please share your complete configuration file? Are you using a profile that supports DPD?

    Please check that you are enabling the DPD init and tracking calibration.

    Please make sure that you are enabling the required DPD parameters.

    typedef struct
    {
    mykonosDacDiv_t dacDiv; /*!< The divider used to generate the DAC clock (ENUM Values)*/
    mykonosFir_t *txFir; /*!< Pointer to Tx FIR filter structure */
    uint8_t txFirInterpolation; /*!< The TX digital FIR filter interpolation (1,2,4) */
    uint8_t thb1Interpolation; /*!< Tx Halfband1 (HB1) filter interpolation (1,2) */
    uint8_t thb2Interpolation; /*!< Tx Halfband2 (HB2) filter interpolation (1,2) */
    uint8_t txInputHbInterpolation; /*!< Interpolation of half band filter before the programmable FIR (valid 1,2,4) */
    uint32_t iqRate_kHz; /*!< Tx IQ data rate in kHz */
    uint32_t primarySigBandwidth_Hz; /*!< Tx primary signal BW */
    uint32_t rfBandwidth_Hz; /*!< Tx RF passband bandwidth for the profile */
    uint32_t txDac3dBCorner_kHz; /*!< DAC filter 3dB corner in kHz */
    uint32_t txBbf3dBCorner_kHz; /*!< Tx BBF 3dB corner in kHz */
    uint8_t enableDpdDataPath; /*!< Enable Tx Dynamic pre distortion - only valid for a DPD-enabled transceiver */
    } mykonosTxProfile_t;

  • Hi ,

    Thanks for your help, I had configure DPD done . But  the result of using DPD in different frequency is different. Here is result once use DPD:

    In 4,5G:

    In 4.6G:

    In 4.8G:

    Here is dpd config:

    static mykonosDpdConfig_t dpdConfig =

        5,              /* 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 */
        16384,            /* 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)*/

    static mykonosObsRxSettings_t obsRxSettings =
    {
        &orxProfile,    /* ORx datapath profile, 3dB corner frequencies, and digital filter enables*/
        &orxGainControl,/* ObsRx gain control settings structure*/
        &obsRxAgcConfig,/* ORx AGC control settings structure*/
        &snifferProfile,/* Sniffer datapath profile, 3dB corner frequencies, and digital filter enables*/
        &snifferGainControl,/* SnRx gain control settings structure*/
        &obsRxFramer,   /* ObsRx JESD204b framer configuration structure */
        MYK_ORX2,
    //    (MYK_ORX1_ORX2 | MYK_SNRXA_B_C),/* obsRxChannel */
        OBSLO_TX_PLL,   /* (obsRxLoSource) The Obs Rx mixer can use the Tx Synth(TX_PLL) or Sniffer Synth (SNIFFER_PLL) */
        4467000000U,     /* SnRx PLL LO frequency in Hz */
        0,              /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data*/
        NULL,           /* Custom Loopback ADC profile to set the bandwidth of the ADC response */
        OBS_RXOFF       /* Default ObsRx channel to enter when radioOn called */
    };

    And here is section that configure DPD:

    	ad9528Device_t 		*clockAD9528_device = &clockAD9528_;
    	mykonosDpdStatus_t  dpdStatus;
    	mykonosErr_t		mykError;
    	const char			*errorString;
    	uint8_t				pllLockStatus;
    	uint8_t				mcsStatus;
    	uint8_t				arm_major;
    	uint8_t				arm_minor;
    	uint8_t				arm_release;
    	mykonosGpioErr_t	mykGpioErr;
    	uint32_t			initCalMask = TX_BB_FILTER | ADC_TUNER | TIA_3DB_CORNER | DC_OFFSET |
    									  TX_ATTENUATION_DELAY | RX_GAIN_DELAY | FLASH_CAL |
    									  PATH_DELAY | TX_LO_LEAKAGE_INTERNAL | TX_QEC_INIT |
    									  LOOPBACK_RX_LO_DELAY | LOOPBACK_RX_RX_QEC_INIT |
    									  RX_LO_DELAY | RX_QEC_INIT ;
    
    
    	uint8_t				errorFlag = 0;
    	uint8_t				errorCode = 0;
    	uint32_t			initCalsCompleted;
    	uint8_t				framerStatus;
    	uint8_t				obsFramerStatus;
    	uint8_t				deframerStatus;
    	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;
    
    	/* Allocating memory for the errorString */
    	errorString = (const char*) malloc(sizeof(char) * 200);
    
    	/*************************************************************************/
    	/*****                Mykonos Initialization Sequence                *****/
    	/*************************************************************************/
    	mykDevice.tx->txChannels = u8TxID;
    	mykDevice.rx->rxChannels = u8RxID;
    
    	/* Perform a hard reset on the MYKONOS DUT (Toggle RESETB pin on device) */
    	if ((mykError = MYKONOS_resetDevice(&mykDevice)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((mykError = MYKONOS_initialize(&mykDevice)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	/*************************************************************************/
    	/*****                Mykonos CLKPLL Status Check                    *****/
    	/*************************************************************************/
    
    	if ((mykError = MYKONOS_checkPllsLockStatus(&mykDevice, &pllLockStatus)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	/*************************************************************************/
    	/*****                Mykonos Perform MultiChip Sync                 *****/
    	/*************************************************************************/
    
    	if ((mykError = MYKONOS_enableMultichipSync(&mykDevice, 1, &mcsStatus)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	/* Minimum 3 SYSREF pulses from Clock Device has to be produced for MulticChip Sync */
    	AD9528_requestSysref(clockAD9528_device, 1);
    	mdelay(1);
    	AD9528_requestSysref(clockAD9528_device, 1);
    	mdelay(1);
    	AD9528_requestSysref(clockAD9528_device, 1);
    	mdelay(1);
    	AD9528_requestSysref(clockAD9528_device, 1);
    	mdelay(1);
    
    	/*************************************************************************/
    	/*****                Mykonos Verify MultiChip Sync                 *****/
    	/*************************************************************************/
    
    	if ((mykError = MYKONOS_enableMultichipSync(&mykDevice, 0, &mcsStatus)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((mcsStatus & 0x0B) == 0x0B)
    		xil_printf("\r\nMCS successful");
    	else
    		xil_printf("\r\nMCS failed\n");
    
    	/*************************************************************************/
    	/*****                Mykonos Load ARM file                          *****/
    	/*************************************************************************/
    
    	if (pllLockStatus & 0x01) {
    		xil_printf("\r\nCLKPLL locked");
    		if ((mykError = MYKONOS_initArm(&mykDevice)) != MYKONOS_ERR_OK) {
    			errorString = getMykonosErrorMessage(mykError);
    //			goto error;
    		}
    
    		if ((mykError = MYKONOS_loadArmFromBinary(&mykDevice, &firmware_Mykonos_M3_bin[0], firmware_Mykonos_M3_bin_len)) != MYKONOS_ERR_OK) {
    			errorString = getMykonosErrorMessage(mykError);
    //			goto error;
    		}
    	} else {
    		xil_printf("\r\nCLKPLL not locked (0x%x)", pllLockStatus);
    		return;
    	}
    
    //	/* Read back the version of the ARM binary loaded into the Mykonos ARM memory */
    //	if ((mykError = MYKONOS_getArmVersion(&mykDevice, &arm_major, &arm_minor, &arm_release, NULL)) == MYKONOS_ERR_OK)
    //		xil_printf("\r\nAD9371 ARM version %d.%d.%d", arm_major, arm_minor, arm_release);
    
    	/*************************************************************************/
    	/*****                Mykonos Set RF PLL Frequencies                 *****/
    	/*************************************************************************/
    	xil_printf("\r\nmykDevice.rx->rxPllLoFrequency_Hz = %ld", mykDevice.rx->rxPllLoFrequency_Hz);
    //	getchar();
    	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, RX_PLL, mykDevice.rx->rxPllLoFrequency_Hz)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    	xil_printf("\r\nmykDevice.tx->txPllLoFrequency_Hz = %ld", mykDevice.tx->txPllLoFrequency_Hz);
    //	getchar();
    	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, TX_PLL, mykDevice.tx->txPllLoFrequency_Hz)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    	xil_printf("\r\nmykDevice.obsRx->snifferPllLoFrequency_Hz = %ld", mykDevice.obsRx->snifferPllLoFrequency_Hz);
    //	getchar();
    	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, SNIFFER_PLL, mykDevice.obsRx->snifferPllLoFrequency_Hz)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	sleep(1);
    
    	if ((mykError = MYKONOS_checkPllsLockStatus(&mykDevice, &pllLockStatus)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    	}
    
    	if ((pllLockStatus & 0x0F) == 0x0F)
    		xil_printf("\r\nPLLs locked");
    	else {
    		xil_printf("\r\nPLLs not locked (0x%x)", pllLockStatus);
    		return;
    	}
    
    #if DPD_ENABLE
    
    	mykError = MYKONOS_configDpd(&mykDevice);
    	if (mykError != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error_11;
    	}
    
    	mykError = MYKONOS_configClgc(&mykDevice);
    	if (mykError != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error_11;
    	}
    
    	mykError = MYKONOS_configVswr(&mykDevice);
    	if (mykError != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error_11;
    	}
    
    #endif
    
    	/*************************************************************************/
    	/*****                Mykonos Set GPIOs                              *****/
    	/*************************************************************************/
    
    	if ((mykGpioErr = MYKONOS_setRx1GainCtrlPin(&mykDevice, 0, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK) {
    		errorString = getGpioMykonosErrorMessage(mykGpioErr);
    //		goto error;
    	}
    
    	if ((mykGpioErr = MYKONOS_setRx2GainCtrlPin(&mykDevice, 0, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK) {
    		errorString = getGpioMykonosErrorMessage(mykGpioErr);
    //		goto error;
    	}
    //	xil_printf("\r\n setTx2AttenCtrlPin");
    //	getchar();
    	if ((mykGpioErr = MYKONOS_setTx1AttenCtrlPin(&mykDevice, 0, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK) {
    		errorString = getGpioMykonosErrorMessage(mykGpioErr);
    //		goto error;
    	}
    //	xil_printf("\r\n setTx2AttenCtrlPin");
    //	getchar();
    	if ((mykGpioErr = MYKONOS_setTx2AttenCtrlPin(&mykDevice, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK) {
    		errorString = getGpioMykonosErrorMessage(mykGpioErr);
    //		goto error;
    	}
    //	xil_printf("\r\n setupGpio");
    //	getchar();
    	if ((mykGpioErr = MYKONOS_setupGpio(&mykDevice)) != MYKONOS_ERR_GPIO_OK) {
    		errorString = getGpioMykonosErrorMessage(mykGpioErr);
    //		goto error;
    	}
    
    	/*************************************************************************/
    	/*****                Mykonos Set manual gains values                *****/
    	/*************************************************************************/
    
    	if ((mykError = MYKONOS_setRx1ManualGain(&mykDevice, 255)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((mykError = MYKONOS_setRx2ManualGain(&mykDevice, 255)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_RX1_TXLO, 255)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_RX2_TXLO, 255)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_SNIFFER_A, 255)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_SNIFFER_B, 255)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_SNIFFER_C, 255)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	/*************************************************************************/
    	/*****                Mykonos Initialize attenuations                *****/
    	/*************************************************************************/
    //	xil_printf("\r\n setTx1Attenuation");
    //	getchar();
    	if ((mykError = MYKONOS_setTx1Attenuation(&mykDevice, 0)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    //	xil_printf("\r\n setTx2Attenuation");
    //	getchar();
    	if ((mykError = MYKONOS_setTx2Attenuation(&mykDevice, 0)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	/*************************************************************************/
    	/*****           Mykonos ARM Initialization Calibrations             *****/
    	/*************************************************************************/
    
        if ((mykError = MYKONOS_runInitCals(&mykDevice, (initCalMask & ~TX_LO_LEAKAGE_EXTERNAL))) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((mykError = MYKONOS_waitInitCals(&mykDevice, 60000, &errorFlag, &errorCode)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((errorFlag != 0) || (errorCode != 0)) {
    		/*** < Info: abort init cals > ***/
    		if ((mykError = MYKONOS_abortInitCals(&mykDevice, &initCalsCompleted)) != MYKONOS_ERR_OK) {
    			errorString = getMykonosErrorMessage(mykError);
    //			goto error;
    		}
    		if (initCalsCompleted)
    			xil_printf("\r\nCompleted calibrations: %x", (unsigned int)initCalsCompleted);
    	}
    	else
    		xil_printf("\r\nCalibrations completed successfully\n");
    
    	/*************************************************************************/
    	/*****  Mykonos ARM Initialization External LOL Calibrations with PA *****/
    	/*************************************************************************/
    
    	/* Please ensure PA is enabled operational at this time */
    	if (initCalMask & TX_LO_LEAKAGE_EXTERNAL) {
    		if ((mykError = MYKONOS_runInitCals(&mykDevice, TX_LO_LEAKAGE_EXTERNAL)) != MYKONOS_ERR_OK) {
    			errorString = getMykonosErrorMessage(mykError);
    //			goto error;
    		}
    
    		if ((mykError = MYKONOS_waitInitCals(&mykDevice, 60000, &errorFlag, &errorCode)) != MYKONOS_ERR_OK) {
    			errorString = getMykonosErrorMessage(mykError);
    //			goto error;
    		}
    
    		if ((errorFlag != 0) || (errorCode != 0)) {
    			/*** < Info: abort init cals > ***/
    			if ((mykError = MYKONOS_abortInitCals(&mykDevice, &initCalsCompleted)) != MYKONOS_ERR_OK) {
    				errorString = getMykonosErrorMessage(mykError);
    //				goto error;
    			}
    		} else
    			xil_printf("External LOL Calibrations completed successfully\n");
    	}
    
    	/*************************************************************************/
    	/*****             SYSTEM JESD bring up procedure                    *****/
    	/*************************************************************************/
    
    	if ((mykError = MYKONOS_enableSysrefToRxFramer(&mykDevice, 1)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    	/*** < Info: Mykonos is waiting for sysref in order to start
    	 * transmitting CGS from the RxFramer> ***/
    
    	if ((mykError = MYKONOS_enableSysrefToObsRxFramer(&mykDevice, 1)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    	/*** < Info: Mykonos is waiting for sysref in order to start
    	 * transmitting CGS from the ObsRxFramer> ***/
    
    	if ((mykError = MYKONOS_enableSysrefToDeframer(&mykDevice, 0)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	if ((mykError = MYKONOS_resetDeframer(&mykDevice)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    
    	if ((mykError = MYKONOS_enableSysrefToDeframer(&mykDevice, 1)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	/*************************************************************************/
    	/*****            Enable SYSREF to Mykonos and BBIC                  *****/
    	/*************************************************************************/
    
    	/* Request a SYSREF from the AD9528 */
    	AD9528_requestSysref(clockAD9528_device, 1);
    	mdelay(1);
    
    	/*** < Info: Mykonos is actively transmitting CGS from the RxFramer> ***/
    
    	/*** < Info: Mykonos is actively transmitting CGS from the ObsRxFramer> ***/
    
    	/* Request two SYSREFs from the AD9528 */
    	AD9528_requestSysref(clockAD9528_device, 1);
    	mdelay(1);
    	AD9528_requestSysref(clockAD9528_device, 1);
    	mdelay(5);
    
    	/*************************************************************************/
    	/*****               Check Mykonos Framer Status                     *****/
    	/*************************************************************************/
    
    	if ((mykError = MYKONOS_readRxFramerStatus(&mykDevice, &framerStatus)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	} else
    		if (framerStatus != 0x3E)
    			xil_printf("\r\nRxFramerStatus = 0x%x", framerStatus);
    
    	if ((mykError = MYKONOS_readOrxFramerStatus(&mykDevice, &obsFramerStatus)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	} else
    		if (obsFramerStatus != 0x3E)
    			xil_printf("\r\nOrxFramerStatus = 0x%x", obsFramerStatus);
    
    	/*************************************************************************/
    	/*****               Check Mykonos Deframer Status                   *****/
    	/*************************************************************************/
    
    	if ((mykError = MYKONOS_readDeframerStatus(&mykDevice, &deframerStatus)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	} else
    		if (deframerStatus != 0x68)
    			xil_printf("\r\nDeframerStatus = 0x%x", deframerStatus);
    
    	/*************************************************************************/
    	/*****           Mykonos enable tracking calibrations                *****/
    	/*************************************************************************/
    
    	if ((mykError = MYKONOS_enableTrackingCals(&mykDevice, trackingCalMask)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	/*** < Info: Allow Rx1/2 QEC tracking and Tx1/2 QEC tracking to run when in the radioOn state
    	     *  Tx calibrations will only run if radioOn and the obsRx path is set to OBS_INTERNAL_CALS > ***/
    
    	/*** < Info: Function to turn radio on, Enables transmitters and receivers
    	 * that were setup during MYKONOS_initialize() > ***/
    	if ((mykError = MYKONOS_radioOn(&mykDevice)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    #if DPD_ENABLE
    	/*************************************************************************/
    	/*****            Enable DPD calibrations                            *****/
    	/*************************************************************************/
    	uint32_t initCalMaskDpd = initCalMask | 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));
    
    	}
    	// 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));
    	}
    
    	xil_printf("Mykonos ARM Initialization Calibrations for DPD");
    
    	if ((mykError = MYKONOS_runInitCals(&mykDevice, (initCalMaskDpd & ~TX_LO_LEAKAGE_EXTERNAL))) != 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));
    
    	}
    
    	if ((mykError = MYKONOS_radioOn(&mykDevice)) != MYKONOS_ERR_OK)
    	{
    		/*** < Info: errorString will contain log error string in order to debug why radioOn failed > ***/
    		//errorString = getMykonosErrorMessage(mykError);
    		puts(getMykonosErrorMessage(mykError));
    
    	}
    
    #endif
    
    
    
    	/*** < Info: Allow TxQEC to run when User: is not actively using ORx receive path > ***/
    	if ((mykError = MYKONOS_setObsRxPathSource(&mykDevice, OBS_RXOFF)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    	if ((mykError = MYKONOS_setObsRxPathSource(&mykDevice, OBS_INTERNALCALS)) != MYKONOS_ERR_OK) {
    		errorString = getMykonosErrorMessage(mykError);
    //		goto error;
    	}
    
    	xil_printf("\r\nDone");
    	{
    		uint16_t u16ChannelPw = 100;
    		uint16_t powerThreshold = 50;
    
    		MYKONOS_setupPaProtection(&mykDevice, powerThreshold, 5, 5, 1, 1);
    
    		MYKONOS_enablePaProtection(&mykDevice, 1);
    
    		MYKONOS_getDacPower(&mykDevice, TX2, &u16ChannelPw);
    
    		xil_printf("\r\nu16ChannelPw: %d", u16ChannelPw);
    	}
    
        if ((mykError = MYKONOS_getDpdStatus(&mykDevice, mykDevice.tx->txChannels, &dpdStatus)) != MYKONOS_ERR_OK)
        {
        	   puts(getMykonosErrorMessage(mykError));
        }
        else
        {
        	 LREP("\r\nDPDStatus: %d 0x%x 0x%x 0x%x 0x%x 0x%x", dpdStatus.dpdErrorStatus, dpdStatus.dpdExtPathDelay, dpdStatus.dpdIterCount, dpdStatus.dpdMaxAdaptation, dpdStatus.dpdModelErrorPercent, dpdStatus.dpdTrackCount);
        }
    
    	SetTxFreq(mykDevice,  mykDevice.tx->txPllLoFrequency_Hz);
    	usleep(100);
    	SetRxFreq(mykDevice,  mykDevice.rx->rxPllLoFrequency_Hz);
    	usleep(100);
    
    	free((char*)errorString);
    

    Can you suggest to me solution improve DPD run better and result is the same in different frequency? My system operate from 4.4G to 5G

    Thanks and brgs.

  • Can you please share the DPD status for all the frequencies? 

    Did you verify your PA performance across frequency?

    What is the PA you are using? 

  • Hi ,

    Thanks for your help.

    I use PA: TGA 2578-CP operate from 2g to 6G.

    I  just change frequency in runtime and verified DPD status for above frequencies:

    In 4.5G:

     dpdStatus.dpdErrorStatus = 0,

    dpdStatus.dpdExtPathDelay = 0x73E,

    dpdStatus.dpdIterCount = 0xB6,

    dpdStatus.dpdMaxAdaptation = 0x1F92,

    dpdStatus.dpdModelErrorPercent = 0xE,

    dpdStatus.dpdTrackCount = 0xB

    In 4.6G:

    dpdStatus.dpdErrorStatus = 0,

    dpdStatus.dpdExtPathDelay = 0x73E,

    dpdStatus.dpdIterCount = 0x1B,

    dpdStatus.dpdMaxAdaptation = 0xF47,

    dpdStatus.dpdModelErrorPercent = 0x11,

    dpdStatus.dpdTrackCount = 0x1B

    In 4.8G:

    dpdStatus.dpdErrorStatus = 9,

    dpdStatus.dpdExtPathDelay = 0x73E,

    dpdStatus.dpdIterCount = 0x144,

    dpdStatus.dpdMaxAdaptation = 0x1F92,

    dpdStatus.dpdModelErrorPercent = 0x12E,

    dpdStatus.dpdTrackCount = 0x1D

    Then I change frequency 4.5G again and read dpd status:

    dpdStatus.dpdErrorStatus = 0,

    dpdStatus.dpdExtPathDelay = 0x73E,

    dpdStatus.dpdIterCount = 0x25D,

    dpdStatus.dpdMaxAdaptation = 0x1F92,

    dpdStatus.dpdModelErrorPercent = 0x53,

    dpdStatus.dpdTrackCount = 0x24

    Thanks

  • DPD is still working without any errors.

    The power levels for the three measurements seems to be different, at 4.6G power is 2 dB higher than 4.5G. For caparison make sure output powers are same. 

    What is the raw ACLR (without DPD) of PA for same power at frequencies 4,5 G, 4.6G  and  4.8G ?

  • Thanks , May be my system don't have CFR block or PAR not the same in user guide:

    A peak to average ratio
    (PAR) of 7.5 dB to 8.5 dB is typical for a 20 MHz LTE FDD
    waveform post CFR. Note that the CFR operations on the test
    waveforms are precomputed in the GUI software. A CFR block
    is not integrated into the
    AD9375 transceiver.

    Thanks

  • Yes the PAR of the signal needs to be between 7.5dB and 8.5dB for best DPD performance.

  • Hi ,

    I have a question.

    have i must calibration DPD again  use MYKONOS_runInitCals and MYKONOS_enableTrackingCals every change frequency or only calibration DPD once at Initialize and change any frequency without DPD calibration again?

    Thanks

Reply Children
  • Please refer "RF PLL FREQUENCY CHANGE PROCEDURE" in UG 992.

    It is recommended to run init cal each time you change frequency if that is a possibility.

    Also on clipped waveform generation, you can use the DPD GUI. connect to board ,select waveform and required PAR and you can save waveform from GUI.

    For your DPD testing you can use same.

  • Thanks ,

    But why in frequency 4.6G above. although dpdErrorStatus  return 0, spectrum had configure DPD is not different from no have DPD ?

    Thanks

  • What is the raw ACLR (without DPD) of PA for same power at frequencies 4,5 G, 4.6G  and  4.8G ?

  • Hi

    ACLR without DPD:

    4.6G: -30dbc for right adj channel, -35dbc for left adj channel

    4.5G: -29dbc for right adj channel, -33dbc for left adj channel

    4.8: -36dbc for right adj channel, -37dbc for left adj channel

    Here are image of 3 above frequency. Thanks

  • What is your target output power,?

    Above measurements are done at different power and hence the variation in ACLR is more.For comparison you need to make measurements at same output power. You can keep Tx1 as primary (center) so that you can read ACLR directly.

    4.5 -28.54 dBm
    4.6 - -26.84 dBm
    4.8 - 25.4 dBm

    Bandwidth is 22MHz , IS the waveform custom?

    The ACLR is not symmetric, The right and left adjacent are having upto 5 dB variation.You may need to correct that for better DPD performnce.

  • Hi

    My system run custom waveform with bandwidth 21.4Mhz. And now different frequency, output power may be not the same. My target output power is 30dbm. Above system has output power with attenuation 30dbm. 

    You say: "The ACLR is not symmetric, The right and left adjacent are having upto 5 dB variation.You may need to correct that for better DPD performence". So what is the maximum different  variation between right and left adjacent that AD9375 can still DPD? 

  • I don't have a exact value for symmetry , Its recommended to be within +/- 1 dB.

    For different power levels the linearity of PA will be different and different ACLR and DPD correction is as well dependent on that. So I guess what you see is expected.

    Mykonos DPD is good for LDMOS PA's where the memory effects are less. For GAN PA's electron trapping adds to short term memory effects and it becomes difficult for DPD to correct.

  • Thanks ,

    Thanks for your information.

    I have implement DPD successful follow your instruction.

    But there is one problem about consume current. My system have limit consume current is 3A.

    When my system run with output power 30dbm, consume current is 1.2A. Once DPD, consume current suddenly increase 2.2A in 0.2 seconds then return 1.2A after that.

    But once my system run at higher power  33dbm, consume current is 1.4A, Once DPD, consume current suddenly increase over 3A. Over current occur and my system be turn off.

    Can you explain this phenomenon and give me solution.

    Thanks

  • When you say Enable DPD , What function is called ? What is the sequence.? 

    Peak current going high, you can try adding some bulk capacitor to PA drain bias , Say 220 UF. 

    Can you share a wide band span spectrum plot of PA output with DPD enabled., Is the output unstable?

  • Hi

    With output power 30dbm, with DPD enable, spectrum plot stable.

    Here is sequence once change frequency and calib DPD:

    mykonosErr_t		mykError;
    
    
    #if DPD_ENABLE
    
    	/*************************************************************************/
    	/*****            Enable DPD calibrations                            *****/
    	/*************************************************************************/
    	uint8_t				errorFlag = 0;
    	uint8_t				errorCode = 0;
    	uint32_t			initCalsCompleted;
    
    	uint32_t initCalMask = TX_BB_FILTER | ADC_TUNER | TIA_3DB_CORNER | DC_OFFSET |
    										  TX_ATTENUATION_DELAY | RX_GAIN_DELAY | FLASH_CAL |
    										  PATH_DELAY | TX_LO_LEAKAGE_INTERNAL | TX_QEC_INIT |
    										  LOOPBACK_RX_LO_DELAY | LOOPBACK_RX_RX_QEC_INIT |
    										  RX_LO_DELAY | RX_QEC_INIT ;
    
    	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 = initCalMask | DPD_INIT | CLGC_INIT | VSWR_INIT;
    
    
    #endif
    	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 DPD_ENABLE
    
    	// 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));
    	}
    
    	xil_printf("\r\n Mykonos ARM Initialization Calibrations for DPD");
    
    	if ((mykError = MYKONOS_runInitCals(&mykDevice, (initCalMaskDpd & ~TX_LO_LEAKAGE_EXTERNAL))) != 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));
    
    	}
    
    #endif
    
    	MYKONOS_radioOn(&mykDevice);
    
    	return MYKONOS_ERR_OK;