Post Go back to editing

AD9371: LO Leakage Calibration through ORX2

Hello all,

I have AD9371 IC with Zynq ultrascale plus MPSoC on the custom board.

I want to enable TX LO Leakage external calibration through ORX2 ( ORX1 is not connected ).

Kindly tell me how can i do it.

Thanks

Mahima

Parents
  • I have updated the "Mykonos ARM Initialization Calibrations" section in ad9371.c file.

        /*****************************************************/
        /*** Mykonos ARM Initialization Calibrations       ***/
        /*****************************************************/
        
        
        ret = ad9371_init_cal(phy, initCalMask);
        dev_err(&phy->spi->dev, "initCalMask :  (%x)", initCalMask);
        if (ret != MYKONOS_ERR_OK) {
            dev_err(&phy->spi->dev, "ad9371_init_cal error:  %s (%d)",
                getMykonosErrorMessage(ret), ret);
            ret = -EFAULT;
            goto out;
        }
        
        ret = ad9371_set_radio_state(phy, RADIO_ON);
        if (ret) {
            dev_err(&phy->spi->dev, "%s (%d)",
                getMykonosErrorMessage(ret), ret);
            //goto out_disable_obs_rx_clk;
        }

        ret = MYKONOS_setObsRxPathSource(mykDevice, OBS_RX2_TXLO);    
        dev_err(&phy->spi->dev, "MYKONOS_setObsRxPathSource setting to OBS_RX2_TXLO and function return value is :  (%d)", ret);       
        if (ret) {
            dev_err(&phy->spi->dev, "%s (%d)",
                getMykonosErrorMessage(ret), ret);
            ret = -EFAULT;
        }
        
        CMB_wait_ms(500);

        //ad9371_init_cal(phy, TX_LO_LEAKAGE_EXTERNAL);
        ret = ad9371_init_cal(phy, TX_LO_LEAKAGE_EXTERNAL);
        if (ret != MYKONOS_ERR_OK) {
            dev_err(&phy->spi->dev, "ad9371 TX_LO_LEAKAGE_EXTERNAL return value error:  %s (%d)",
                getMykonosErrorMessage(ret), ret);
            ret = -EFAULT;
            goto out;
        }
        
        ret = ad9371_set_radio_state(phy, RADIO_OFF);
        if (ret) {
            dev_err(&phy->spi->dev, "%s (%d)",
                getMykonosErrorMessage(ret), ret);
            //goto out_disable_obs_rx_clk;
        }
        
        ret = MYKONOS_getTxLolStatus(phy->mykDevice, TX1, &phy->txLolStatus[1]);
        dev_err(&phy->spi->dev, "Checking MYKONOS_getTxLolStatus ret value : (%d)",ret);
        if (ret) {
            dev_err(&phy->spi->dev, "Checking MYKONOS_getTxLolStatus %s: %s (%d)", __func__,
                getMykonosErrorMessage(ret), ret);
            return ret;
        }

        if (&phy->txLolStatus[1].errorCode)
            dev_err(&phy->spi->dev, "%s: error code (%d)\n", __func__, &phy->txLolStatus[1].errorCode);
        if (&phy->txLolStatus[1].percentComplete)
            dev_err(&phy->spi->dev, "%s: percentComplete (%d)\n", __func__, &phy->txLolStatus[1].percentComplete);
        if (&phy->txLolStatus[1].performanceMetric)
            dev_err(&phy->spi->dev, "%s: performanceMetric (%d)\n", __func__, &phy->txLolStatus[1].performanceMetric);
        if (&phy->txLolStatus[1].iterCount)
            dev_err(&phy->spi->dev, "%s: iterCount (%d)\n", __func__, &phy->txLolStatus[1].iterCount);
        if (&phy->txLolStatus[1].updateCount)
            dev_err(&phy->spi->dev, "%s: updateCount (%d)\n", __func__, &phy->txLolStatus[1].updateCount);

        
        ret = MYKONOS_getTxLolStatus(phy->mykDevice, TX1, &phy->txLolStatus[2]);
        dev_err(&phy->spi->dev, "Checking MYKONOS_getTxLolStatus ret value : (%d)",ret);
        if (ret) {
            dev_err(&phy->spi->dev, "Checking MYKONOS_getTxLolStatus %s: %s (%d)", __func__,
                getMykonosErrorMessage(ret), ret);
            return ret;
        }

        if (&phy->txLolStatus[2].errorCode)
            dev_err(&phy->spi->dev, "%s: error code (%d)\n", __func__, &phy->txLolStatus[2].errorCode);
        if (&phy->txLolStatus[2].percentComplete)
            dev_err(&phy->spi->dev, "%s: percentComplete (%d)\n", __func__, &phy->txLolStatus[2].percentComplete);
        if (&phy->txLolStatus[2].performanceMetric)
            dev_err(&phy->spi->dev, "%s: performanceMetric (%d)\n", __func__, &phy->txLolStatus[2].performanceMetric);
        if (&phy->txLolStatus[2].iterCount)
            dev_err(&phy->spi->dev, "%s: iterCount (%d)\n", __func__, &phy->txLolStatus[2].iterCount);
        if (&phy->txLolStatus[2].updateCount)
            dev_err(&phy->spi->dev, "%s: updateCount (%d)\n", __func__, &phy->txLolStatus[2].updateCount);

    Log details are:

    [  128.495192] ad9371 spi1.0: initCalMask :  (7dff)
    [  128.535615] ad9371 spi1.0: MYKONOS_setObsRxPathSource setting to OBS_RX2_TXLO and 
    function return value is :  (0)
    [  129.063806] ERROR: 364: MYKONOS_waitArmCmdStatus() exited due to ARM error for 
    the desired ARM opcode
    [  129.073024] ERROR: 283: MYKONOS_waitInitCals() returned an ARM error
    [  129.088077] ad9371 spi1.0: calsDoneLifetime 0x5DFF, calsDoneLastRun 0x5DFF, 
    calsMinimum 0x4F, initErrCal 0x0, initErrCode 0x0
    [  129.131846] ad9371 spi1.0: initCalsCompleted 0x5DFF
    [  129.136903] ad9371 spi1.0: errorWord 0x2, statusWord 0x0
    [  129.142248] ad9371 spi1.0: ArmCmdStatusByte 0x4
    [  129.156600] ad9371 spi1.0: TX_LO_LEAKAGE_EXTERNAL :  (200)
    [  129.184231] ad9371 spi1.0: Checking MYKONOS_getTxLolStatus ret value : (0)
    [  129.191102] ad9371 spi1.0: ad9371_setup_cal_ms: error code (2063315820)
    [  129.197720] ad9371 spi1.0: ad9371_setup_cal_ms: percentComplete (2063315824)
    [  129.204761] ad9371 spi1.0: ad9371_setup_cal_ms: performanceMetric (2063315828)
    [  129.211975] ad9371 spi1.0: ad9371_setup_cal_ms: iterCount (2063315832)
    [  129.218494] ad9371 spi1.0: ad9371_setup_cal_ms: updateCount (2063315836)
    [  129.236232] ad9371 spi1.0: Checking MYKONOS_getTxLolStatus ret value : (0)
    [  129.243100] ad9371 spi1.0: ad9371_setup_cal_ms: error code (2063315840)
    [  129.249714] ad9371 spi1.0: ad9371_setup_cal_ms: percentComplete (2063315844)
    [  129.256759] ad9371 spi1.0: ad9371_setup_cal_ms: performanceMetric (2063315848)
    [  129.263973] ad9371 spi1.0: ad9371_setup_cal_ms: iterCount (2063315852)
    [  129.270492] ad9371 spi1.0: ad9371_setup_cal_ms: updateCount (2063315856)
    [  129.286606] ad9371 spi1.0: deframerStatus (0x68)
    
    >From the above logs, initErrCal is coming as 0x0. This means " Tx baseband filter calibartion " error.
    
     
    
    initErrCode is coming as 0x0. This means " No error".
    
     
    While running TX_LO_LEAKAGE_EXTERNAL calibration, I am getting above error. Please reply.
  • You can ignore percentage complete. That is status of current update and it varies as per what time we print the status. Iter count and update count are same means its working fine. LOL levels are as well good.

     We don’t see an issue here.

  • Thanks

    I have to test same calibration on our custom board with ORX2.

    Is there any function to calculate ORX2 power level?

  • You can use the below API to measure the ORX dec power

    getObsRxDecPower

  • Thanks for the reply.

    I have tried same configuration on our custom board. Hence TX1 LOL external calibration is working with ORX2.

    But LOL is at -61dBc with respect to main frequency in bist mode. Is there any other ways to calibrate more?

  • When you are using the TX1 to ORX2 path for running the external LOL cals, are you seeing good LOL levels? When you are sending tone from FPGA ,are you seeing good LOL levels with TX1 to ORX2 external LOL calibration?

    When you are sending the tone from internal TX NCO, what is the frequency of the tone?

    Can you share a capture of the TX output when you are sending tone using TX NCO?

  • Sorry for the delayed response. I will share the snapshots.

  • The above figure shows bist tone after external LO calibration at TX1 through ORX2

    The above figure shows bist tone before external LO calibration at TX1 through ORX2

  • You are seeing an improvement in LOL levels with External LOL tracking cal enabled. So, it confirms that the cal is running.

     Can you share the status of the  MYKONOS_getTxLolStatus when you are running TX1 to ORX2 external TXLOL cal? hope that the same loopback path is configured in GPIO settings as discussed before.

    If you use TX1 to ORX1 path or TX2 to ORX2 path for running external TXLOL cal, how much LOL levels are you seeing?

  • Yes, improvement is there.

    ad9371 spi1.1: Checking MYKONOS_getTxLolStatus ret value : (0)
    ad9371 spi1.1: ad9371_tx_lol_status: error code (0)
    ad9371 spi1.1: ad9371_tx_lol_status: percentComplete (64)
    ad9371 spi1.1: ad9371_tx_lol_status: performanceMetric (0)
    ad9371 spi1.1: ad9371_tx_lol_status: iterCount (38)
    ad9371 spi1.1: ad9371_tx_lol_status: updateCount (38)

    Yes, same loopback path is configured in GPIO settings.

    We cannot run cal using ORX1 as on our custom board ORX1 is not connected.

  • From the LOL status, it can be confirmed that the external LOL tracking cal is running successfully.

    As per datasheet, you should observe -81dBFs,or, -74dBm. You are observing an LOL of -70dBm, which looks good as per the output tone power level..

    Can you increase the input power level and then check the LOL levels? It will give datasheet performance , Refer to the below conditions from datasheet and test:

    3 dB RF and 3 dB digital attenuation, 40 kHz measurement BW

Reply
  • From the LOL status, it can be confirmed that the external LOL tracking cal is running successfully.

    As per datasheet, you should observe -81dBFs,or, -74dBm. You are observing an LOL of -70dBm, which looks good as per the output tone power level..

    Can you increase the input power level and then check the LOL levels? It will give datasheet performance , Refer to the below conditions from datasheet and test:

    3 dB RF and 3 dB digital attenuation, 40 kHz measurement BW

Children
No Data