Center frequency tuning time after some change

I checked the code, so the cache has been extended to also store LO tuning values, but it was never updated to cache new analog DC calibration values, so it does not work properly.

Here’s code you can use to readback calibration results, and later restore them. Assuming the calibration has been executed at least once, so all the necessary parameter enables would be properly set by the procedure, and you would be just modifying the control values.

//PLL tune same for Rx/Tx just switch channel A(Rx) / B(Tx)
uint16_t reg011D; //FRAC_SDM[15:0]
uint16_t reg011E; //INT_SDM & FRAC_SDM[19:16]
uint16_t div_loch;
uint16_t en_div2;
uint16_t sel_vco;
uint16_t csw_vco;

//readback results
LMS_ReadLMSReg(device, 0x011D, &reg011D);
LMS_ReadLMSReg(device, 0x011E, &reg011E);
LMS_ReadParam(device, LMS7_DIV_LOCH, &div_loch);
LMS_ReadParam(device, LMS7_EN_DIV2_DIVPROG, &en_div2);
LMS_ReadParam(device, LMS7_SEL_VCO, &sel_vco);
LMS_ReadParam(device, LMS7_CSW_VCO, &csw_vco);
//restore results
LMS_WriteLMSReg(device, 0x011D, reg011D);
LMS_WriteLMSReg(device, 0x011E, reg011E);
LMS_WriteParam(device, LMS7_DIV_LOCH, div_loch);
LMS_WriteParam(device, LMS7_EN_DIV2_DIVPROG, en_div2);
LMS_WriteParam(device, LMS7_SEL_VCO, sel_vco);
LMS_WriteParam(device, LMS7_CSW_VCO, csw_vco);


// DC/IQ same for Rx/Tx just adjust the paramter names 
uint16_t gcorri;
uint16_t gcorrq;
uint16_t phaseOffset;
int16_t dci;
int16_t dcq; 

//readback results
LMS_ReadParam(device, LMS7_GCORRI_RXTSP, &gcorri);
LMS_ReadParam(device, LMS7_GCORRQ_RXTSP, &gcorrq);
LMS_ReadParam(device, LMS7_IQCORR_RXTSP, &phaseOffset);
dci = ReadAnalogDC(LMS7_DC_RXAI.address);
dcq = ReadAnalogDC(LMS7_DC_RXAQ.address);

//restore results
LMS_WriteParam(device, LMS7_GCORRI_RXTSP, gcorri);
LMS_WriteParam(device, LMS7_GCORRQ_RXTSP, gcorrq);
LMS_WriteParam(device, LMS7_IQCORR_RXTSP, phaseOffset);
WriteAnalogDC(LMS7_DC_RXAI.address, dci);
WriteAnalogDC(LMS7_DC_RXAQ.address, dcq);

int16_t ReadAnalogDC(const uint16_t addr)
{
	const uint16_t mask = addr < 0x05C7 ? 0x03FF : 0x003F;
	uint16_t value;
	int16_t result;
	LMS_WriteLMSReg(device, addr, 0);
	LMS_WriteLMSReg(device, addr, 0x4000);
	LMS_ReadLMSReg(device, addr, &value);
	LMS_WriteLMSReg(device, addr, value & ~0xC000);
	result = (value & mask);
	if(value & (mask+1))
	    result *= -1;
	return result;
}

void WriteAnalogDC(const uint16_t addr, int16_t value)
{
	const uint16_t mask = addr < 0x05C7 ? 0x03FF : 0x003F;
	int16_t regValue = 0;
	if(value < 0)
	{
	    regValue |= (mask+1);
	    regValue |= (abs(value+mask) & mask);
	}
	else
	    regValue |= (abs(value+mask+1) & mask);
	LMS_WriteLMSReg(device, addr, regValue);
	LMS_WriteLMSReg(device, addr, regValue | 0x8000);
}
2 Likes