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
AD9371
Recommended for New Designs
The AD9371 is a highly integrated, wideband RF transceiver
offering dual channel transmitters and receivers, integrated synthesizers, and digital signal...
Datasheet
AD9371 on Analog.com
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
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.
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.
Are you using external switch to connect Tx1 and Tx2 to ORx2 as shown below.
In this case, the calibration must advise the user which path it wishes to calibrate. It does this through the GPIO pin configured for the txObsSelect output. The user must configure the
txObsSelect output before the external LOL initialization calibration is called (see the ARM GPIOs section). By default, the txObsSelect output indicates that the Tx1 output is to be fed back to the required ORx with a low output on this pin,while a high output indicates that Tx2 is to be fed back. Again,the initialization calibration cycles through both calibrations consecutively; therefore, it is important that both paths are active and that the request to toggle the external switch is responded
to (the ARM expects to see the feedback path settled within35 μs of the state change indicated by the txObsSelect output).
You need to run external LOL init twice with switch position change for Tx1 and Tx2.
Currently in the setup, TX1 data is coming at ORX2 input. No data is available at TX2.
txObsSelect is configured as zero.
Do i have to take care of anything else? Please suggest.
"You need to run external LOL init twice with switch position change for Tx1 and Tx2"
Is it still required when i am doing calibration for one path?
Thanks
Mahima
tx obs select output should be zero, for TX1 output feedback
Have you disabled the TX2 path during initialization using below API?
|
No, the external LOL cal should be run only once, if you need calibration for only one path
Thanks for the reply.
No i have not disabled TX2 path during initialization using this API init_txsettings.
Please tell where i can use this api and i did not find the same in ad9371.c file.
You need to edit the structure mykonosTxSettings_t to the required TX channel and then initialize the chip.
I have changed adi,tx-settings-tx-channels-enable from TX1_TX2 to TX1.
I am getting same error. Please check
[ 145.635551] ad9371_init_cal:583 initCalMask 200
[ 145.640187] ad9371_init_cal:587 Run mykError 0
[ 145.644689] ERROR: 364: MYKONOS_waitArmCmdStatus() exited due to ARM error for the desired ARM opcode
[ 145.653907] ERROR: 283: MYKONOS_waitInitCals() returned an ARM error
[ 145.660250] ad9371_init_cal:592 Wait mykError 11b
[ 145.675980] ad9371_init_cal:596 initCalStatus 5dff
[ 145.680763] ad9371_init_cal:599
[ 145.696031] ad9371 spi1.1: calsDoneLifetime 0x5DFF, calsDoneLastRun 0x5DFF, calsMinimum 0x4F, initErrCal 0x0, initErrCode 0x0
[ 145.739781] ad9371 spi1.1: initCalsCompleted 0x5DFF
[ 145.744835] ad9371 spi1.1: errorWord 0x2, statusWord 0x0
[ 145.750194] ad9371 spi1.1: ArmCmdStatusByte 0x4
As i do not have eval board, can you try on AD9371 eval board by modifying ad9371.c file?
Please check
Can you enable only ORX2 in the init config using the below API and initialize the chip and then check.,i.e, only TX1 and ORX2 should be enabled with a proper external feedback path between both of them.
mykonosObsRxSettings_t
If you disable the external TX LOL cal and then run the init, are you able to pass the initialization with TX1 and ORX2 enabled?
hi srimoyi,
AD9371_OF_PROP("adi,obs-settings-obs-rx-channels-enable", &phy->mykDevice->obsRx->obsRxChannelsEnable, MYK_ORX2);
AD9371_OF_PROP("adi,obs-settings-obs-rx-lo-source", &phy->mykDevice->obsRx->obsRxLoSource, 0);
AD9371_OF_PROP("adi,obs-settings-sniffer-pll-lo-frequency_hz", &phy->mykDevice->obsRx->snifferPllLoFrequency_Hz, 2600000000U);
AD9371_OF_PROP("adi,obs-settings-real-if-data", &phy->mykDevice->obsRx->realIfData, 0);
AD9371_OF_PROP("adi,obs-settings-default-obs-rx-channel", &phy->mykDevice->obsRx->defaultObsRxChannel, OBS_RX2_TXLO);
These are already set in ad9371.c file. Please tell if i have to set any other parameter.
"If you disable the external TX LOL cal and then run the init, are you able to pass the initialization with TX1 and ORX2 enabled? " - I will check
Can you check on Eval board TX LO External calibration with ORX2 ?
Thanks
Mahima