Files
KY-XTZ/src/hardware/headless.c
T

1170 lines
35 KiB
C

/******************************************************************************* * @file ad9371/src/app/headless.c
* @brief Implementation of Main Function.
********************************************************************************
* Copyright 2017(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/***************************** Include Files ********************************/
#include "headless.h"
#include "delay.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Variable Definitions *****************************/
XScuGic Intc;
/************************** Function Prototypes ******************************/
int HARDWARE_initialize()
{
int Status;
// use configuration
mykDevice.rx->rxPllLoFrequency_Hz = 720000000u;
mykDevice.tx->txPllLoFrequency_Hz = 720000000u;
mykDevice.tx->tx1Atten_mdB = 10000;
mykDevice.tx->tx2Atten_mdB = 10000;
Status = HARDWARE_ad9371Config();
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
// /**********************************************************/
// /************ AD9371 Dynamical Reconfiguration ************/
// /**********************************************************/
// Status = HW_ad9371DynamicCfgInit();
// if (Status != ADIERR_OK){
// HW_PRINT("HW:: AD9371 dynamic configuration initialization failed!\n");
// return ADIERR_FAILED;
// }
//
// HW_PRINT("HW:: AD9371 ready to be reconfigured!\n");
//
// // main loop
// while(1);
// never reach
return ADIERR_OK;
}
// this function is NOT safe
int HARDWARE_ad9371Config(void)
{
int Status;
uint8_t reg508;
uint8_t framerStatus;
uint8_t obsFramerStatus;
uint8_t deframerStatus;
/**********************************************************/
/*********** Initialize Configuration Interface ***********/
/**********************************************************/
Status = CMB_initPlatform();
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
Status = HW_adiCfgProfileInit();
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
HW_PRINT("HW:: Initialize configuration interface done!\n");
/**********************************************************/
/****************** AD9528 Configuration ******************/
/**********************************************************/
Status = HW_9528Config(ad9528Init);
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
HW_PRINT("HW:: AD9528 configuration done!\n");
Status = HW_9528GetLockStatus(ad9528Init, &reg508);
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
HW_PRINT("HW:: AD9528 REG508: 0x%02x\n", reg508);
/**********************************************************/
/****************** AD9371 Configuration ******************/
/**********************************************************/
Status = HW_9371Config(ad9528Init, &mykDevice);
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
Status = HW_9371CheckJesdStatus(&mykDevice, &framerStatus,
&obsFramerStatus, &deframerStatus);
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
else
{
// typical value: 0x3E
HW_PRINT("HW:: RxFramerStatus = 0x%x\n", framerStatus);
// typical value: 0x3E
HW_PRINT("HW:: OrxFramerStatus = 0x%x\n", obsFramerStatus);
// typical value: 0x28
HW_PRINT("HW:: DeframerStatus = 0x%x\n", deframerStatus);
}
HW_PRINT("HW:: All configuration done!\n");
return ADIERR_OK;
}
// this function is NOT safe
// int HW_ad9371DynamicCfgInit(void)
//{
// int Status;
//
// Status = HW_setupIntrSystem(INTC_DEVICE_ID, &Intc);
// if (Status != XST_SUCCESS) {
// HW_PRINT("HW: HW_setupIntrSystem() failed!\n");
// return XST_FAILURE;
// }
//
// Status = XGpio_Initialize(&GpioFreqCtrl, FREQ_CTRL_DEVICE_ID);
// Status |= XGpio_Initialize(&GpioGainCtrl, GAIN_CTRL_DEVICE_ID);
// Status |= XGpio_Initialize(&GpioAttnCtrl, ATTN_CTRL_DEVICE_ID);
// if (Status != XST_SUCCESS) {
// HW_PRINT("HW: GPIO init failed!\n");
// return XST_FAILURE;
// }
//
// /* Set the direction for all signals as inputs. */
// XGpio_SetDataDirection(&GpioFreqCtrl, AXI_GPIO_BANK_1, 0xFFFFFFFF);
// XGpio_SetDataDirection(&GpioFreqCtrl, AXI_GPIO_BANK_2, 0xFFFFFFFF);
//
// XGpio_SetDataDirection(&GpioGainCtrl, AXI_GPIO_BANK_1, 0xFFFFFFFF);
// XGpio_SetDataDirection(&GpioGainCtrl, AXI_GPIO_BANK_2, 0xFFFFFFFF);
//
// XGpio_SetDataDirection(&GpioAttnCtrl, AXI_GPIO_BANK_1, 0xFFFFFFFF);
// XGpio_SetDataDirection(&GpioAttnCtrl, AXI_GPIO_BANK_2, 0xFFFFFFFF);
//
// Status = HW_connectIntr(&Intc, FREQ_CTRL_INTR_ID,
// (Xil_InterruptHandler)FreqIntrHandler, &GpioFreqCtrl, 0xA0, 0x3);
// Status |= HW_connectIntr(&Intc, GAIN_CTRL_INTR_ID,
// (Xil_InterruptHandler)GainIntrHandler, &GpioGainCtrl, 0xA0, 0x3);
// Status |= HW_connectIntr(&Intc, ATTN_CTRL_INTR_ID,
// (Xil_InterruptHandler)AttnIntrHandler, &GpioAttnCtrl, 0xA0, 0x3);
//
// XGpio_InterruptEnable(&GpioFreqCtrl, XGPIO_IR_MASK);
// XGpio_InterruptGlobalEnable(&GpioFreqCtrl);
//
// XGpio_InterruptEnable(&GpioGainCtrl, XGPIO_IR_MASK);
// XGpio_InterruptGlobalEnable(&GpioGainCtrl);
//
// XGpio_InterruptEnable(&GpioAttnCtrl, XGPIO_IR_MASK);
// XGpio_InterruptGlobalEnable(&GpioAttnCtrl);
//
// return XST_SUCCESS;
//}
/*****************************************************************************/
/*
*
* This function setups the interrupt system.
*
* @param DeviceId is the unique identifier for a GIC device.
* @param GicPtr is a pointer to the instance of the INTC.
*
* @return
* - XST_SUCCESS if successful,
* - XST_FAILURE.if not succesful
*
* @note None.
*
******************************************************************************/
int HW_setupIntrSystem(u16 DeviceId, XScuGic *GicPtr)
{
int Status;
XScuGic_Config *CfgPtr;
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
CfgPtr = XScuGic_LookupConfig(DeviceId);
if (!CfgPtr)
{
HW_PRINT("No interrupt config found for %d\n", DeviceId);
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(GicPtr, CfgPtr, CfgPtr->CpuBaseAddress);
if (Status != XST_SUCCESS)
{
HW_PRINT("No interrupt config found for %d\n", DeviceId);
return XST_FAILURE;
}
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
(void *)GicPtr);
Xil_ExceptionEnable();
return XST_SUCCESS;
}
int HW_connectIntr(XScuGic *GicPtr, u32 IntrId, Xil_InterruptHandler Handler,
void *CallBackRef, u8 Priority, u8 Trigger)
{
int Status;
// Register interrupt handler
Status = XScuGic_Connect(GicPtr, IntrId, (Xil_InterruptHandler)Handler,
CallBackRef);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
XScuGic_SetPriorityTriggerType(GicPtr, IntrId, Priority, Trigger);
XScuGic_Enable(GicPtr, IntrId);
return XST_SUCCESS;
}
int HW_adiCfgProfileInit(void)
{
if (!ad9528Init)
{
HW_PRINT("Cannot find ad9528 configuration profile with name 'ad9528Init'!");
return ADIERR_FAILED;
}
ad9528Init->spiSettings->chipSelectIndex = AD9528_CS;
mykDevice.spiSettings->chipSelectIndex = AD9371_CS;
mykDevice.rx->framer->serializerLanesEnabled = 0x03;
mykDevice.rx->framer->serializerLaneCrossbar = 0xE4;
mykDevice.obsRx->framer->serializerLanesEnabled = 0x04;
mykDevice.tx->deframer->deserializerLanesEnabled = 0x03;
mykDevice.tx->deframer->deserializerLaneCrossbar = 0xE4;
return ADIERR_OK;
}
int HW_9528Config(ad9528Device_t *clockAD9528_device)
{
ADI_ERR error;
/**************************************************************************/
/***** System Clocks Initialization Initialization Sequence *****/
/**************************************************************************/
/* Perform a hard reset on the AD9528 DUT */
error = AD9528_resetDevice(clockAD9528_device);
if (error != ADIERR_OK)
{
HW_PRINT("AD9528_resetDevice() failed\n");
return ADIERR_FAILED;
}
error = AD9528_initDeviceDataStruct(clockAD9528_device,
clockAD9528_device->pll1Settings->vcxo_Frequency_Hz,
clockAD9528_device->pll1Settings->refA_Frequency_Hz,
clockAD9528_device->outputSettings->outFrequency_Hz[1]);
if (error != ADIERR_OK)
{
HW_PRINT("AD9528_initDeviceDataStruct() failed\n");
return ADIERR_FAILED;
}
/* Initialize the AD9528 by writing all SPI registers */
error = AD9528_initialize(clockAD9528_device);
if (error != ADIERR_OK)
{
HW_PRINT("WARNING: AD9528_initialize() issues.\n");
}
return ADIERR_OK;
}
int HW_9528GetLockStatus(ad9528Device_t *device, uint8_t *reg508)
{
ADI_ERR error;
error = CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, reg508);
if (error != ADIERR_OK)
{
HW_PRINT("HW_9528GetLockStatus failed.\n");
return ADIERR_FAILED;
}
return ADIERR_OK;
}
int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice)
{
ADI_ERR error;
mykonosErr_t mykError;
const char *errorString;
uint8_t pllLockStatus;
uint8_t mcsStatus;
uint8_t arm_major;
uint8_t arm_minor;
uint8_t arm_release;
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;
uint32_t trackingCalMask = TRACK_ORX1_QEC | TRACK_ORX2_QEC | TRACK_RX1_QEC |
TRACK_RX2_QEC | TRACK_TX1_QEC | TRACK_TX2_QEC;
/* Allocating memory for the errorString */
errorString = NULL;
/*************************************************************************/
/***** Mykonos Initialization Sequence *****/
/*************************************************************************/
/* 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_11;
}
if ((mykError = MYKONOS_initialize(mykDevice)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
/*************************************************************************/
/***** Mykonos CLKPLL Status Check *****/
/*************************************************************************/
if ((mykError = MYKONOS_checkPllsLockStatus(mykDevice,
&pllLockStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
/*************************************************************************/
/***** Mykonos Perform MultiChip Sync *****/
/*************************************************************************/
if ((mykError = MYKONOS_enableMultichipSync(mykDevice, 1,
&mcsStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
/* 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_11;
}
if ((mcsStatus & 0x0B) == 0x0B)
HW_PRINT("MCS successful\n");
else
HW_PRINT("MCS failed\n");
/*************************************************************************/
/***** Mykonos Load ARM file *****/
/*************************************************************************/
if (pllLockStatus & 0x01)
{
HW_PRINT("CLKPLL locked\n");
if ((mykError = MYKONOS_initArm(mykDevice)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_loadArmFromBinary(mykDevice,
&firmware_Mykonos_M3_bin[0], firmware_Mykonos_M3_bin_len)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
}
else
{
HW_PRINT("CLKPLL not locked (0x%x)\n", pllLockStatus);
error = ADIERR_FAILED;
goto error_2;
}
/* 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)
HW_PRINT("AD9371 ARM version %d.%d.%d\n", arm_major, arm_minor, arm_release);
/*************************************************************************/
/***** Mykonos Set RF PLL Frequencies *****/
/*************************************************************************/
if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, RX_PLL,
mykDevice->rx->rxPllLoFrequency_Hz)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, TX_PLL,
mykDevice->tx->txPllLoFrequency_Hz)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, SNIFFER_PLL,
mykDevice->obsRx->snifferPllLoFrequency_Hz)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
/* Wait 200ms for PLLs to lock */
mdelay(200);
if ((mykError = MYKONOS_checkPllsLockStatus(mykDevice,
&pllLockStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((pllLockStatus & 0x0F) == 0x0F)
HW_PRINT("PLLs locked\n");
else
{
HW_PRINT("PLLs not locked (0x%x)\n", pllLockStatus);
error = ADIERR_FAILED;
goto error_2;
}
// /*************************************************************************/
// /***** Mykonos Set GPIOs *****/
// /*************************************************************************/
//
// if ((mykGpioErr = MYKONOS_setRx1GainCtrlPin(mykDevice, 0, 0, 0, 0,
// 0)) != MYKONOS_ERR_GPIO_OK) {
// errorString = getGpioMykonosErrorMessage(mykGpioErr);
// goto error_11;
// }
//
// if ((mykGpioErr = MYKONOS_setRx2GainCtrlPin(mykDevice, 0, 0, 0, 0,
// 0)) != MYKONOS_ERR_GPIO_OK) {
// errorString = getGpioMykonosErrorMessage(mykGpioErr);
// goto error_11;
// }
//
// if ((mykGpioErr = MYKONOS_setTx1AttenCtrlPin(mykDevice, 0, 0, 0, 0,
// 0)) != MYKONOS_ERR_GPIO_OK) {
// errorString = getGpioMykonosErrorMessage(mykGpioErr);
// goto error_11;
// }
//
// if ((mykGpioErr = MYKONOS_setTx2AttenCtrlPin(mykDevice, 0, 0, 0,
// 0)) != MYKONOS_ERR_GPIO_OK) {
// errorString = getGpioMykonosErrorMessage(mykGpioErr);
// goto error_11;
// }
//
// if ((mykGpioErr = MYKONOS_setupGpio(mykDevice)) != MYKONOS_ERR_GPIO_OK) {
// errorString = getGpioMykonosErrorMessage(mykGpioErr);
// goto error_11;
// }
//
// /*************************************************************************/
// /***** Mykonos Set manual gains values *****/
// /*************************************************************************/
//
// if ((mykError = MYKONOS_setRx1ManualGain(mykDevice, 255)) != MYKONOS_ERR_OK) {
// errorString = getMykonosErrorMessage(mykError);
// goto error_11;
// }
//
// if ((mykError = MYKONOS_setRx2ManualGain(mykDevice, 255)) != MYKONOS_ERR_OK) {
// errorString = getMykonosErrorMessage(mykError);
// goto error_11;
// }
//
// if ((mykError = MYKONOS_setObsRxManualGain(mykDevice, OBS_RX1_TXLO,
// 255)) != MYKONOS_ERR_OK) {
// errorString = getMykonosErrorMessage(mykError);
// goto error_11;
// }
//
// if ((mykError = MYKONOS_setObsRxManualGain(mykDevice, OBS_RX2_TXLO,
// 255)) != MYKONOS_ERR_OK) {
// errorString = getMykonosErrorMessage(mykError);
// goto error_11;
// }
//
// if ((mykError = MYKONOS_setObsRxManualGain(mykDevice, OBS_SNIFFER_A,
// 255)) != MYKONOS_ERR_OK) {
// errorString = getMykonosErrorMessage(mykError);
// goto error_11;
// }
//
// if ((mykError = MYKONOS_setObsRxManualGain(mykDevice, OBS_SNIFFER_B,
// 255)) != MYKONOS_ERR_OK) {
// errorString = getMykonosErrorMessage(mykError);
// goto error_11;
// }
//
// if ((mykError = MYKONOS_setObsRxManualGain(mykDevice, OBS_SNIFFER_C,
// 255)) != MYKONOS_ERR_OK) {
// errorString = getMykonosErrorMessage(mykError);
// goto error_11;
// }
//
// /*************************************************************************/
// /***** Mykonos Initialize attenuations *****/
// /*************************************************************************/
//
// mykError = MYKONOS_setTx1Attenuation(mykDevice, 10000);
// if (mykError != MYKONOS_ERR_OK) {
// errorString = getMykonosErrorMessage(mykError);
// goto error_11;
// }
//
// mykError = MYKONOS_setTx2Attenuation(mykDevice, 10000);
// if (mykError != MYKONOS_ERR_OK) {
// errorString = getMykonosErrorMessage(mykError);
// goto error_11;
// }
/*************************************************************************/
/***** Mykonos ARM Initialization Calibrations *****/
/*************************************************************************/
if ((mykError = MYKONOS_runInitCals(mykDevice,
(initCalMask & ~TX_LO_LEAKAGE_EXTERNAL))) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_waitInitCals(mykDevice, 60000, &errorFlag,
&errorCode)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((errorFlag != 0) || (errorCode != 0))
{
/*** < Info: abort init cals > ***/
if ((mykError = MYKONOS_abortInitCals(mykDevice,
&initCalsCompleted)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if (initCalsCompleted)
HW_PRINT("Completed calibrations: %x\n", (unsigned int)initCalsCompleted);
}
else
HW_PRINT("Calibrations 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_11;
}
if ((mykError = MYKONOS_waitInitCals(mykDevice, 60000, &errorFlag,
&errorCode)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((errorFlag != 0) || (errorCode != 0))
{
/*** < Info: abort init cals > ***/
if ((mykError = MYKONOS_abortInitCals(mykDevice,
&initCalsCompleted)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
}
else
HW_PRINT("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_11;
}
/*** < 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_11;
}
/*** < 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_11;
}
if ((mykError = MYKONOS_resetDeframer(mykDevice)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_enableSysrefToDeframer(mykDevice, 1)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
/*************************************************************************/
/***** 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);
/*************************************************************************/
/***** Mykonos enable tracking calibrations *****/
/*************************************************************************/
if ((mykError = MYKONOS_enableTrackingCals(mykDevice,
trackingCalMask)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
/*** < 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_11;
}
/*** < 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_11;
}
if ((mykError = MYKONOS_setObsRxPathSource(mykDevice,
OBS_INTERNALCALS)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
mdelay(1000);
if ((mykError = MYKONOS_setObsRxPathSource(mykDevice,
OBS_RX1_SNIFFERLO)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
Xil_DCacheInvalidateRange(DDR_MEM_BASEADDR + 0x800000, 16384 * 8);
HW_PRINT("Done\n");
return 0;
error_11:
HW_PRINT("%s", errorString);
error_2:
// axi_clkgen_remove(rx_clkgen);
return FAILURE;
}
int HW_9371CheckJesdStatus(mykonosDevice_t *mykDevice, uint8_t *framerStatus,
uint8_t *obsFramerStatus, uint8_t *deframerStatus)
{
mykonosErr_t mykError;
const char *errorString;
/* Allocating memory for the errorString */
errorString = NULL;
/*************************************************************************/
/***** Check Mykonos Framer Status *****/
/*************************************************************************/
if ((mykError = MYKONOS_readRxFramerStatus(mykDevice,
framerStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
return ADIERR_FAILED;
}
else
{
// typical value: 0x3E
}
if ((mykError = MYKONOS_readOrxFramerStatus(mykDevice,
obsFramerStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
return ADIERR_FAILED;
}
else
{
// typical value: 0x3E
}
/*************************************************************************/
/***** Check Mykonos Deframer Status *****/
/*************************************************************************/
if ((mykError = MYKONOS_readDeframerStatus(mykDevice,
deframerStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
return ADIERR_FAILED;
}
else
{
// typical value: 0x28
}
return ADIERR_OK;
}
int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
{
mykonosErr_t mykError = MYKONOS_ERR_OK;
uint8_t pllLockStatus = 0;
/*
* Move the device into the radio off state.
*/
if ((mykError = MYKONOS_radioOff(mykDevice)) != MYKONOS_ERR_OK)
{
HW_PRINT("Turn radio off failed!\n\r");
return ADIERR_FAILED;
}
/*
* Program the new local oscillator (LO) frequency. Check if PLL is locked.
*/
if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, TX_PLL,
freq_Hz)) != MYKONOS_ERR_OK)
{
HW_PRINT("Set TX PLL failed!\n\r");
return ADIERR_FAILED;
}
mykError = MYKONOS_checkPllsLockStatus(mykDevice, &pllLockStatus);
if ((pllLockStatus & 0x07) != 0x07)
{
/*** < Info: Clock, Rx and Tx PLLs not locked > ***/
HW_PRINT("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus);
}
/*
* Reset the external channel.
*/
// If((mykError = MYKONOS_resetExtTxLolChannel(mykDevice, TX1_TX2))
// != MYKONOS_ERR_OK) ; //where TX1_TX2 is part of the enum mykonosTxChannels_t
// {
// HW_PRINT("Reset external channel FAILED!");
// }
/*
* Move the device back into the radio on state.
*/
if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK)
{
HW_PRINT("Turn radio on failed!\n\r");
return ADIERR_FAILED;
}
/*
* Reenable tracking calibrations.
*/
// If((mykError = MYKONOS_MYKONOS_setObsRxPathSource(mykDevice, OBS_INTERNALCALS))
// != MYKONOS_ERR_OK) ; //where TX1_TX2 is part of the enum mykonosTxChannels_t
// {
// HW_PRINT("Reenable tracking calibrations FAILED!");
// }
return ADIERR_OK;
}
int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
{
mykonosErr_t mykError = MYKONOS_ERR_OK;
uint8_t pllLockStatus = 0;
uint8_t errorFlag = 0;
uint8_t errorCode = 0;
uint32_t initCalsCompleted = 0;
uint16_t errorWord = 0;
uint16_t statusWord = 0;
uint8_t status = 0;
mykonosInitCalStatus_t initCalStatus = {0};
/*
* Move the device into the radio off state.
*/
if ((mykError = MYKONOS_radioOff(mykDevice)) != MYKONOS_ERR_OK)
{
HW_PRINT("Turn radio off failed!\n\r");
return ADIERR_FAILED;
}
/*
* Program the new local oscillator (LO) frequency. Check if PLL is locked.
*/
if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, TX_PLL,
freq_Hz)) != MYKONOS_ERR_OK)
{
HW_PRINT("Set TX PLL failed!\n\r");
return ADIERR_FAILED;
}
mykError = MYKONOS_checkPllsLockStatus(mykDevice, &pllLockStatus);
if ((pllLockStatus & 0x07) != 0x07)
{
/*** < Info: Clock, Rx and Tx PLLs not locked > ***/
HW_PRINT("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus);
}
/*
* Rerun the initialization calibrations.
*/
uint32_t initCalMask = TX_QEC_INIT | LOOPBACK_RX_LO_DELAY |
LOOPBACK_RX_RX_QEC_INIT | RX_LO_DELAY | RX_QEC_INIT;
if ((mykError = MYKONOS_runInitCals(mykDevice, initCalMask)) != MYKONOS_ERR_OK)
{
HW_PRINT("Rerun the initialization calibrations FAILED!");
return ADIERR_FAILED;
}
if ((mykError = MYKONOS_waitInitCals(mykDevice, 60000, &errorFlag,
&errorCode)) != MYKONOS_ERR_OK)
{
HW_PRINT("Initialize calibration TIME OUT!");
return ADIERR_FAILED;
}
if ((errorFlag != 0) || (errorCode != 0))
{
HW_PRINT("initial cals error!\n\r");
if ((mykError = MYKONOS_getInitCalStatus(mykDevice, &initCalStatus)) != MYKONOS_ERR_OK)
{
/*** < User log error return value to debug why init failed > ***/
}
// abort init calibrations
if ((mykError = MYKONOS_abortInitCals(mykDevice, &initCalsCompleted)) != MYKONOS_ERR_OK)
{
/*** < User log error return value to debug why init failed > ***/
}
if (initCalsCompleted)
{
/*** < which calls had completed, per the mask > ***/
}
if ((mykError = MYKONOS_readArmCmdStatus(mykDevice, &errorWord,
&statusWord)) != MYKONOS_ERR_OK)
{
/*** < User log error return value to debug why init failed > ***/
}
if ((mykError = MYKONOS_readArmCmdStatusByte(mykDevice, 2, &status)) != MYKONOS_ERR_OK)
{
}
if (status != 0)
{
/*** < Arm Mailbox Status Error errorWord > ***/
/*** < Pending Flag per opcode statusWord, this follows the mask > ***/
}
}
/*
* Move the device back into the radio on state.
*/
if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK)
{
HW_PRINT("Turn radio on failed!\n\r");
return ADIERR_FAILED;
}
return ADIERR_OK;
}
// void FreqIntrHandler(void *CallbackRef)
// {
// XGpio *GpioPtr = (XGpio *)CallbackRef;
// uint8_t IntrStatus;
// uint32_t NewFreqHz;
// IntrStatus = XGpio_InterruptGetStatus(GpioPtr);
// if (IntrStatus & XGPIO_IR_CH1_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH1_MASK);
// NewFreqHz = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_1);
// if (NewFreqHz != mykDevice.tx->txPllLoFrequency_Hz)
// {
// if (NewFreqHz > 300000000 && NewFreqHz < 6000000000)
// {
// if (abs(NewFreqHz - mykDevice.tx->txPllLoFrequency_Hz) <= 100000000)
// {
// HW_9371SmallFrequencyChange(&mykDevice, NewFreqHz);
// }
// else
// {
// HW_9371LargeFrequencyChange(&mykDevice, NewFreqHz);
// }
// mykDevice.tx->txPllLoFrequency_Hz = NewFreqHz;
// HW_PRINT("New Tx frequency set to %d Hz!\n", NewFreqHz);
// }
// else
// {
// HW_PRINT("The desired Tx Frequency is out of range(300 ~ 6000 MHz)!\n");
// }
// }
// }
// if (IntrStatus & XGPIO_IR_CH2_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH2_MASK);
// NewFreqHz = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_2);
// if (NewFreqHz != mykDevice.rx->rxPllLoFrequency_Hz)
// {
// if (NewFreqHz > 300000000 && NewFreqHz < 6000000000)
// {
// if (abs(NewFreqHz - mykDevice.rx->rxPllLoFrequency_Hz) <= 100000000)
// {
// HW_9371SmallFrequencyChange(&mykDevice, NewFreqHz);
// }
// else
// {
// HW_9371LargeFrequencyChange(&mykDevice, NewFreqHz);
// }
// mykDevice.rx->rxPllLoFrequency_Hz = NewFreqHz;
// HW_PRINT("New Rx frequency set to %d Hz!\n", NewFreqHz);
// }
// else
// {
// HW_PRINT("The desired Rx Frequency is out of range(300 ~ 6000 MHz)!\n");
// }
// }
// }
// }
// void GainIntrHandler(void *CallbackRef)
// {
// XGpio *GpioPtr = (XGpio *)CallbackRef;
// uint8_t IntrStatus;
// uint32_t NewRxGain;
// IntrStatus = XGpio_InterruptGetStatus(GpioPtr);
// if (IntrStatus & XGPIO_IR_CH1_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH1_MASK);
// NewRxGain = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_1);
// if (NewRxGain != mykDevice.rx->rxGainCtrl->rx1GainIndex)
// {
// if ((NewRxGain >= 195) && (NewRxGain <= 255))
// {
// MYKONOS_setRx1ManualGain(&mykDevice, NewRxGain);
// mykDevice.rx->rxGainCtrl->rx1GainIndex = NewRxGain;
// char buf[BUFSIZ];
// sHW_PRINT(buf, "%u", NewRxGain);
// HW_PRINT("New Rx1 gain index set to %s!\n", buf);
// }
// else
// {
// HW_PRINT("The desired Rx1 gain index is out of range(195 ~ 255), 0.5dB per stage!\n");
// }
// }
// }
// if (IntrStatus & XGPIO_IR_CH2_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH2_MASK);
// NewRxGain = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_2);
// if (NewRxGain != mykDevice.rx->rxGainCtrl->rx2GainIndex)
// {
// if ((NewRxGain >= 195) && (NewRxGain <= 255))
// {
// MYKONOS_setRx2ManualGain(&mykDevice, NewRxGain);
// mykDevice.rx->rxGainCtrl->rx2GainIndex = NewRxGain;
// char buf[BUFSIZ];
// sHW_PRINT(buf, "%u", NewRxGain);
// HW_PRINT("New Rx2 gain index set to %s!\n", buf);
// }
// else
// {
// HW_PRINT("The desired Rx2 gain index is out of range(195 ~ 255), 0.5dB per stage!\n");
// }
// }
// }
// }
// void AttnIntrHandler(void *CallbackRef)
// {
// XGpio *GpioPtr = (XGpio *)CallbackRef;
// uint8_t IntrStatus;
// uint32_t NewTxAttn;
// IntrStatus = XGpio_InterruptGetStatus(GpioPtr);
// if (IntrStatus & XGPIO_IR_CH1_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH1_MASK);
// NewTxAttn = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_1);
// if (NewTxAttn != mykDevice.tx->tx1Atten_mdB)
// {
// if ((NewTxAttn >= 0) && (NewTxAttn <= 41950))
// {
// MYKONOS_setTx1Attenuation(&mykDevice, NewTxAttn);
// mykDevice.tx->tx1Atten_mdB = NewTxAttn;
// char buf[BUFSIZ];
// sHW_PRINT(buf, "%u", NewTxAttn);
// HW_PRINT("New Tx1 attenuation set to %s dBm!\n", buf);
// }
// else
// {
// HW_PRINT("The desired Tx1 attenuation is out of range(0 ~ 41950 dBm), 50 dBm step!\n");
// }
// }
// }
// if (IntrStatus & XGPIO_IR_CH2_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH2_MASK);
// NewTxAttn = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_2);
// if (NewTxAttn != mykDevice.tx->tx2Atten_mdB)
// {
// if ((NewTxAttn >= 0) && (NewTxAttn <= 41950))
// {
// MYKONOS_setTx2Attenuation(&mykDevice, NewTxAttn);
// mykDevice.tx->tx2Atten_mdB = NewTxAttn;
// char buf[BUFSIZ];
// sHW_PRINT(buf, "%u", NewTxAttn);
// HW_PRINT("New Tx2 attenuation set to %s dBm!\n", buf);
// }
// else
// {
// HW_PRINT("The desired Tx2 attenuation is out of range(0 ~ 41950 dBm), 50 dBm step!\n");
// }
// }
// }
// }