/*****************************************************************************/ /** * Description: hwconfig.h * * Date: 2024-02-20 13:19 * Last Edit Time: [2024-02-20 13:19] * * Revisions: Rev 0.0 * History: * [2023-05-07]: Initial edition. * * Copyright(c) 2024 Beijing Institute of Technology. * ******************************************************************************/ /***************************** Include Files *********************************/ // Standard #include #include // Xilinx #include "xgpiops.h" #include "drivers/axi_core/spi_engine/spi_engine.h" // App #include "common.h" #include "error.h" #include "delay.h" #include "system_monitor.h" #include "hwconfig.h" #include "config/app_config.h" #include "dev_profile/dev_profile.h" #ifdef RFSOC #include "xrfdc.h" #endif /************************** Function Prototypes ******************************/ /*********************** Driver Instance Definitions **************************/ static struct hmc7044_dev *hmc7044_inst; ad9528Device_t *ad9528_inst; static struct lmk04828_dev *lmk04828_inst; static struct lmx2594_dev *lmx2594_adc_inst; static struct lmx2594_dev *lmx2594_dac_inst; static struct ad9361_reg_dev *ad9361_1_reg_inst; static struct ad9361_reg_dev *ad9361_2_reg_inst; static struct ad9361_rf_phy *ad9361_phy; static struct ad9653_dev *ad9653_inst; static struct ad9694_dev *ad9694_inst; XGpioPs Gpio; #ifdef RFSOC XRFdc RFdc; #endif /*****************************************************************************/ /** * @brief Hardware_Init * * @param none. * * @return None. * ******************************************************************************/ int32_t Hardware_Init(void) { int32_t Status; // gpio initialization XGpioPs_Config *ConfigPtr; ConfigPtr = XGpioPs_LookupConfig(AD9361_GPIO_DEVICE_ID); Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr); if (Status != SUCCESS) { return FAILURE; } #ifdef RFSOC /**********************************************************/ /************* RF Data Converter Configuration ************/ /**********************************************************/ // rf data converter initialization XRFdc_Config *RFdc_ConfigPtr; RFdc_ConfigPtr = XRFdc_LookupConfig(RFDC_DEVICE_ID); Status = XRFdc_CfgInitialize(&RFdc, RFdc_ConfigPtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } mdelay(100); #endif #ifdef HMC7044 /**********************************************************/ /****************** HMC7044 Configuration *****************/ /**********************************************************/ Status = hmc7044_init(&hmc7044_inst, &hmc7044_default_init_param); if (Status != SUCCESS) { DBG_ERROR("HDWR: hmc7044_init() error: %" PRId32 "\n", Status); return FAILURE; } #endif #ifdef AD9528 /**********************************************************/ /****************** AD9528 Configuration ******************/ /**********************************************************/ Status = AD9528_init(&ad9528_inst, &ad9528_default_init_param); if (Status != SUCCESS) { DBG_ERROR("HDWR: AD9528_init() error: %" PRId32 "\n", Status); return FAILURE; } Status = AD9528_config(ad9528_inst); if (Status != SUCCESS) { return FAILURE; DBG_ERROR("HDWR: AD9528_config() error: %" PRId32 "\n", Status); } #endif #ifdef LMK04828 /**********************************************************/ /***************** LMK04828 Configuration *****************/ /**********************************************************/ Status = lmk04828_init(&lmk04828_inst, &lmk04828_default_init_param); for(int i = 0; i < lmk04828_default_config_len; i++) { Status = lmk04828_write(lmk04828_inst, lmk04828_default_config[i].addr, lmk04828_default_config[i].value); if (lmk04828_default_config[i].addr == 0x0000) { mdelay(500); } } uint8_t Lmk04828Read; // check pll1 lock status Status = lmk04828_read(lmk04828_inst, 0x0182, &Lmk04828Read); if ((Lmk04828Read & 0x02) == 0x02) { DBG_INFO("HDWR: [LMK04828] PLL1 Locked.\r\n"); } else { DBG_ERROR("HDWR: [LMK04828] PLL1 NOT lock. It takes a while " "for PLL1 to lock. Lock status is shown on LED.\r\n"); } // check pll2 lock status Status = lmk04828_read(lmk04828_inst, 0x0183, &Lmk04828Read); if ((Lmk04828Read & 0x02) == 0x02) { DBG_INFO("HDWR: [LMK04828] PLL2 Locked.\r\n"); } else { DBG_INFO("HDWR: [LMK04828] PLL2 NOT lock!\r\n"); } #endif #ifdef LMX2594_ADC /**********************************************************/ /************* LMX2594 for ADC Configuration **************/ /**********************************************************/ Status = lmx2594_init(&lmx2594_adc_inst, &lmx2594_adc_init_param); for(int i = 0; i < lmx2594_default_config_len; i++) { Status = lmx2594_write(lmx2594_adc_inst, lmx2594_default_config[i].addr, lmx2594_default_config[i].value); if (lmx2594_default_config[i].addr == 0) { mdelay(500); } } uint16_t Lmx2594AdcRead; // check vco lock status Status = lmx2594_read(lmx2594_adc_inst, 110, &Lmx2594AdcRead); if (((Lmx2594AdcRead >> 9) & 0x0003) == 0x0002) { DBG_INFO("HDWR: [ADC LMX2594] Config Done.\r\n"); } else { DBG_INFO("HDWR: [ADC LMX2594] not lock!\r\n"); } // set mux out to lock status Status = lmx2594_write(lmx2594_adc_inst, 0x00, 0x259C); DBG_INFO("HDWR: [ADC LMX2594] SPI readback disabled, " "lock status is shown on LED.\r\n"); #endif #ifdef LMX2594_DAC /**********************************************************/ /************* LMX2594 for DAC Configuration **************/ /**********************************************************/ Status = lmx2594_init(&lmx2594_dac_inst, &lmx2594_dac_init_param); for(int i = 0; i < lmx2594_default_config_len; i++) { Status = lmx2594_write(lmx2594_dac_inst, lmx2594_default_config[i].addr, lmx2594_default_config[i].value); if (lmx2594_default_config[i].addr == 0) { mdelay(500); } } uint16_t Lmx2594DacRead; // check vco lock status Status = lmx2594_read(lmx2594_dac_inst, 110, &Lmx2594DacRead); if (((Lmx2594DacRead >> 9) & 0x0003) == 0x0002) { DBG_INFO("HDWR: [DAC LMX2594] Config Done.\r\n"); } else { DBG_INFO("HDWR: [DAC LMX2594] not lock!\r\n"); } // set mux out to lock status Status = lmx2594_write(lmx2594_dac_inst, 0x00, 0x259C); DBG_INFO("HDWR: [DAC LMX2594] SPI readback disabled, " "lock status is shown on LED.\r\n"); #endif #if defined(AD9361_API) || defined(AD9361_REG) /**********************************************************/ /***************** AD9361-1 Configuration *****************/ /**********************************************************/ XGpioPs_SetDirectionPin(&Gpio, AD9361_1_TXNRX, AD9361_GPIO_OUTPUT); XGpioPs_SetDirectionPin(&Gpio, AD9361_1_ENABLE, AD9361_GPIO_OUTPUT); XGpioPs_SetDirectionPin(&Gpio, AD9361_1_EN_AGC, AD9361_GPIO_OUTPUT); XGpioPs_SetDirectionPin(&Gpio, AD9361_1_RESET_B, AD9361_GPIO_OUTPUT); #ifdef AD9361_REG ad9361_reg_init(&ad9361_1_reg_inst, &ad9361_1_reg_default_init_param); XGpioPs_WritePin(&Gpio, AD9361_1_ENABLE, 0); ad9361_reg_config(ad9361_1_reg_inst); XGpioPs_WritePin(&Gpio, AD9361_1_ENABLE, 1); #endif #ifdef AD9361_API Status = ad9361_init(&ad9361_phy, &ad9361_default_init_param); if (Status != XST_SUCCESS){ DBG_ERROR("HDWR: ad9361_init() error: %" PRId32 "\n", Status); return XST_FAILURE; } ad9361_set_tx_fir_config(ad9361_phy, tx_fir_config); ad9361_set_rx_fir_config(ad9361_phy, rx_fir_config); #endif /**********************************************************/ /***************** AD9361-2 Configuration *****************/ /**********************************************************/ XGpioPs_SetDirectionPin(&Gpio, AD9361_2_TXNRX, AD9361_GPIO_OUTPUT); XGpioPs_SetDirectionPin(&Gpio, AD9361_2_ENABLE, AD9361_GPIO_OUTPUT); XGpioPs_SetDirectionPin(&Gpio, AD9361_2_EN_AGC, AD9361_GPIO_OUTPUT); XGpioPs_SetDirectionPin(&Gpio, AD9361_2_RESET_B, AD9361_GPIO_OUTPUT); ad9361_reg_init(&ad9361_2_reg_inst, &ad9361_2_reg_default_init_param); XGpioPs_WritePin(&Gpio, AD9361_2_ENABLE, 0); ad9361_reg_config(ad9361_2_reg_inst); XGpioPs_WritePin(&Gpio, AD9361_2_ENABLE, 1); // uint8_t rd_back; // Status = ad9361_reg_read(ad9361_1_reg_inst, 0x0002, &rd_back); // Status = ad9361_reg_read(ad9361_2_reg_inst, 0x0002, &rd_back); Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0109, 0x00); // Rx Gain Status = ad9361_reg_write(ad9361_1_reg_inst, 0x010C, 0x00); // Rx Gain Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0109, 0x00); // Rx Gain Status = ad9361_reg_write(ad9361_2_reg_inst, 0x010C, 0x00); // Rx Gain #endif #ifdef AD9653 Status = ad9653_init(&ad9653_inst, &ad9653_default_init_param); for(int i = 0; i < ad9653_default_config_len; i++){ Status = ad9653_write(ad9653_inst, ad9653_default_config[i].addr, ad9653_default_config[i].value); if (ad9653_default_config[i].addr == 0x0000){ mdelay(500); } } #endif #ifdef AD9694 /**********************************************************/ /****************** AD9694 Configuration ******************/ /**********************************************************/ Status = ad9694_init(&ad9694_inst, &ad9694_default_init_param); for(int i = 0; i < ad9694_default_config_len; i++){ Status = ad9694_write(ad9694_inst, ad9694_default_config[i].addr, ad9694_default_config[i].value); if (ad9694_default_config[i].addr == 0x0000){ mdelay(500); } } // uint8_t reg0008; // uint8_t reg056F; // uint8_t reg0571; // // ad9694_read(ad9694_inst,0x008,®0008); // ad9694_read(ad9694_inst,0x56F,®056F); // ad9694_read(ad9694_inst,0x571,®0571); #endif #ifdef RFSOC /* * DAC Mapping: * Number Tile Block * 1 (VOUT_00) 228 (XRFDC_TILE_ID0) DAC 0/DUC 0 (XRFDC_BLK_ID0) * 2 (VOUT_02) 228 (XRFDC_TILE_ID0) DAC 1/DUC 2 (XRFDC_BLK_ID2) * 3 (VOUT_10) 229 (XRFDC_TILE_ID1) DAC 1/DUC 0 (XRFDC_BLK_ID0) * 4 (VOUT_12) 229 (XRFDC_TILE_ID1) DAC 1/DUC 2 (XRFDC_BLK_ID2) * 5 (VOUT_20) 230 (XRFDC_TILE_ID2) DAC 0/DUC 0 (XRFDC_BLK_ID0) * 6 (VOUT_22) 230 (XRFDC_TILE_ID2) DAC 1/DUC 2 (XRFDC_BLK_ID2) * 7 (VOUT_30) 231 (XRFDC_TILE_ID3) DAC 0/DUC 0 (XRFDC_BLK_ID0) * 8 (VOUT_32) 231 (XRFDC_TILE_ID3) DAC 1/DUC 2 (XRFDC_BLK_ID2) * */ // // get & set mixer settings // XRFdc_Mixer_Settings Mixer_Settings_DAC; // // // 3th channel // Status = XRFdc_GetMixerSettings(&RFdc, XRFDC_DAC_TILE, XRFDC_TILE_ID1, // XRFDC_BLK_ID0, &Mixer_Settings_DAC); // if (Status != XST_SUCCESS) { // return XST_FAILURE; // } // // Mixer_Settings_DAC.Freq = 1500; // // Status = XRFdc_SetMixerSettings(&RFdc, XRFDC_DAC_TILE, XRFDC_TILE_ID1, // XRFDC_BLK_ID0, &Mixer_Settings_DAC); // if (Status != XST_SUCCESS) { // return XST_FAILURE; // } // // mdelay(100); // // Status = XRFdc_UpdateEvent(&RFdc, XRFDC_DAC_TILE, XRFDC_TILE_ID1, // XRFDC_BLK_ID0, XRFDC_EVENT_MIXER); // if (Status != XST_SUCCESS) { // return XST_FAILURE; // } /* * ADC Mapping: * Number Tile Block * 1 (VIN0_01) 224 (XRFDC_TILE_ID0) ADC 0 (XRFDC_BLK_ID0) * 2 (VIN0_12) 224 (XRFDC_TILE_ID0) ADC 1 (XRFDC_BLK_ID1) * 3 (VIN1_01) 225 (XRFDC_TILE_ID1) ADC 0 (XRFDC_BLK_ID0) * 4 (VIN1_23) 225 (XRFDC_TILE_ID1) ADC 1 (XRFDC_BLK_ID1) * 5 (VIN2_01) 226 (XRFDC_TILE_ID2) ADC 0 (XRFDC_BLK_ID0) * 6 (VIN2_23) 227 (XRFDC_TILE_ID2) ADC 1 (XRFDC_BLK_ID1) * 7 (VIN3_01) 224 (XRFDC_TILE_ID0) ADC 0 (XRFDC_BLK_ID0) * 8 (VIN3_23) 227 (XRFDC_TILE_ID3) ADC 1 (XRFDC_BLK_ID1) * */ // // get & set mixer settings // XRFdc_Mixer_Settings Mixer_Settings_ADC; // // // 3rd channel // Status = XRFdc_GetMixerSettings(&RFdc, XRFDC_ADC_TILE, XRFDC_TILE_ID1, // XRFDC_BLK_ID0, &Mixer_Settings_ADC); // if (Status != XST_SUCCESS) { // return XST_FAILURE; // } // // Mixer_Settings_ADC.Freq = 1500; // Mixer_Settings_ADC.EventSource = XRFDC_EVNT_SRC_TILE; // // Status = XRFdc_SetMixerSettings(&RFdc, XRFDC_ADC_TILE, XRFDC_TILE_ID1, // XRFDC_BLK_ID0, &Mixer_Settings_ADC); // if (Status != XST_SUCCESS) { // return XST_FAILURE; // } // // mdelay(100); // // Status = XRFdc_UpdateEvent(&RFdc, XRFDC_ADC_TILE, XRFDC_TILE_ID1, // XRFDC_BLK_ID0, XRFDC_EVENT_MIXER); // if (Status != XST_SUCCESS) { // return XST_FAILURE; // } #endif DBG_INFO("HDWR: Configuration Done.\n"); return SUCCESS; } // @ Get AD9361 - 1 temperature (Celsius Degree) /** * Read corresponding register to get AD9361 - 1 current temperature. */ int8_t Hardware_GetAD9361Temp_1(void) { ASSERT(ad9361_1_reg_inst != NULL); int8_t scaleTemp; double temp; ad9361_reg_write(ad9361_1_reg_inst, 0x000B, -64); ad9361_reg_write(ad9361_1_reg_inst, 0x001D, 0x01); // disable aux adc ad9361_reg_read(ad9361_1_reg_inst, 0x000E, (uint8_t*)&scaleTemp); ad9361_reg_write(ad9361_1_reg_inst, 0x001D, 0x00); // enable aux adc temp = ((double)scaleTemp + 64)/1.16; return ((temp > INT8_MAX) ? INT8_MAX : (int8_t)temp); } // @ Get AD9361 - 2 temperature (Celsius Degree) /** * Read corresponding register to get AD9361 - 2 current temperature. */ int8_t Hardware_GetAD9361Temp_2(void) { ASSERT(ad9361_2_reg_inst != NULL); int8_t scaleTemp; double temp; ad9361_reg_write(ad9361_2_reg_inst, 0x000B, -64); ad9361_reg_write(ad9361_2_reg_inst, 0x001D, 0x01); // disable aux adc ad9361_reg_read(ad9361_2_reg_inst, 0x000E, (uint8_t*)&scaleTemp); ad9361_reg_write(ad9361_2_reg_inst, 0x001D, 0x00); // enable aux adc temp = ((double)scaleTemp + 64)/1.16; return ((temp > INT8_MAX) ? INT8_MAX : (int8_t)temp); } // @ Determine AD9361 lock state /** * Read corresponding register to determine AD9361(both) lock state. */ uint8_t Hardware_GetAD9361LockStatus(void) { ASSERT(ad9361_1_reg_inst != NULL && ad9361_2_reg_inst != NULL); uint8_t ret = 0; uint8_t regVal; // bbpll ad9361_reg_read(ad9361_1_reg_inst, 0x005E, ®Val); // [D7] is lock indicator ret |= ((regVal & 0x80) == 0x80) ? CLK_AD0_BBPLL_LOCK : 0; ad9361_reg_read(ad9361_2_reg_inst, 0x005E, ®Val); // [D7] is lock indicator ret |= ((regVal & 0x80) == 0x80) ? CLK_AD1_BBPLL_LOCK : 0; // rfpll ad9361_reg_read(ad9361_1_reg_inst, 0x0287, ®Val); // [D1] is lock indicator ret |= ((regVal & 0x02) == 0x02) ? CLK_AD0_RFPLL_LOCK : 0; ad9361_reg_read(ad9361_2_reg_inst, 0x0287, ®Val); // [D1] is lock indicator ret |= ((regVal & 0x02) == 0x02) ? CLK_AD1_RFPLL_LOCK : 0; return ret; } // @ Determine HMC7044 lock state /** * Read corresponding register to determine clock lock state. */ uint8_t Hardware_GetHMC7044LockStatus(void) { ASSERT(hmc7044_inst != NULL); uint8_t ret = 0; uint8_t regVal; // pll1 hmc7044_read(hmc7044_inst, 0x007C, ®Val); // [D5] is lock indicator ret |= ((regVal & 0xE0) != 0x00) ? CLK_SP_PLL1_LOCK : 0; // pll2 hmc7044_read(hmc7044_inst, 0x007D, ®Val); // [D0] is lock indicator ret |= ((regVal & 0x01) == 0x01) ? CLK_SP_PLL2_LOCK : 0; return ret; } // @ Determine AD9528 lock state /** * Read corresponding register to determine clock lock state. */ uint8_t Hardware_GetAD9528LockStatus(void) { ASSERT(ad9528_inst != NULL); uint8_t ret = 0; uint8_t regVal; // pll1 AD9528_spiReadByte(ad9528_inst, AD9528_ADDR_STATUS_READBACK0, ®Val); // [D0] is lock indicator ret |= ((regVal & 0x01) == 0x01) ? CLK_SP_PLL1_LOCK : 0; // pll2 AD9528_spiReadByte(ad9528_inst, AD9528_ADDR_STATUS_READBACK0, ®Val); // [D1] is lock indicator ret |= ((regVal & 0x02) == 0x02) ? CLK_SP_PLL2_LOCK : 0; return ret; }