/******************************************************************************* * @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, ®508); 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"); // } // } // } // }