XilinxProcessorIPLib/drivers/dfeccf/examples/xdfesi570_mgt.c
u32 XDfeSi570_SetFrequency(double CurrentFrequency, double NewFrequency)
{
	const u8 XDfeSi570_HS_DIV[XDFESI570_HS_DIV_MAX_ID] = {
		4U, 5U, 6U, 7U, XDFESI570_NOT_USED, 9U, XDFESI570_NOT_USED, 11U
	};

	u8 Addr = XDFESI570_CONTROL_REG;
	u8 MuxAddr = 0x8U;
	u8 Tx = 1U;
	u8 Rx[20];
	u64 Rx_new;
	u32 Index = 0;
	u64 RFREQ;
	u64 RFREQ_new;
	double RFREQ_f;
	double f_RFREQ_new;
	u32 N;
	u32 N_new;
	u32 HS_DIV;
	double f_xtal;
	double f_dco;

	/* Set a control register address (0x87=135) and set recall NVM to RAM */
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr, 1U,
			    MuxAddr);
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Tx, 1U,
			    MuxAddr);

	/* Set a si570 register address and read data */
	for (Addr = XDFESI570_N1_HS_DIV_REG; Addr <= XDFESI570_RFREQ_LSB_REG;
	     Addr++) {
		XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr,
				    1U, MuxAddr);
		XDfeSi570_I2CRdData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570,
				    &Rx[Index], 1U, MuxAddr);
		Index++;
	}

	/* Prepare parameters for calculation */
	RFREQ = (((u64)(Rx[1] & 0x3fU)) << 32U) + (Rx[2] << 24U) +
		(Rx[3] << 16U) + (Rx[4] << 8U) + Rx[5];
	RFREQ_f = (double)((double)RFREQ / (1U << 28U));
	N = (((Rx[0] & 0x1fU) << 2U) | ((Rx[1] & 0xc0U) >> 6U)) + 1U;
	HS_DIV = XDfeSi570_HS_DIV[(Rx[0] & 0xE0U) >> 5U];
	f_xtal = (CurrentFrequency * N * HS_DIV) / RFREQ_f;

	/* Search N and HS_DIV to be in range [4.85GHz,5.67GHz] */
	for (N_new = 1U; N_new <= XDFESI570_CLKOUT_DIVIDER_MAX; N_new++) {
		/* valid are all even numbers and 1 */
		if ((N_new != 1U) && (N_new != 2U * (N_new / 2U))) {
			continue;
		}
		for (Index = 0; Index < XDFESI570_HS_DIV_MAX_ID; Index++) {
			HS_DIV = XDfeSi570_HS_DIV[Index];
			if (HS_DIV == XDFESI570_NOT_USED) {
				continue;
			}
			f_dco = NewFrequency * N_new * HS_DIV;
			if ((XDFESI570_DCO_MIN < f_dco) &&
			    (f_dco < XDFESI570_DCO_MAX)) {
				goto exit_loop;
			}
		}
		N_new += 2U;
	}
	LOG("Not available setting");
	return XST_FAILURE;

exit_loop:
	/* Find RFREQ for the chosen N and HS_DIV */
	f_RFREQ_new = f_dco / f_xtal;
	RFREQ_new = (u64)(f_RFREQ_new * (1U << 28U));

	/* Sort RFREQ into u8 array */
	Rx_new = RFREQ_new + ((u64)(N_new - 1U) << 38U);
	for (Index = 0; Index < 6U; Index++) {
		Rx[Index] = Rx_new & 0xffU;
		Rx_new = Rx_new >> 8U;
	}

	/* Freeze oscillator in register address (0x89=137) */
	Addr = XDFESI570_FREEZE_DCO_REG;
	Tx = XDFESI570_FREEZE_DCO;
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr, 1U,
			    MuxAddr);
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Tx, 1U,
			    MuxAddr);

	/* Set a si570 register address and write data */
	Index = 0;
	for (Addr = XDFESI570_N1_HS_DIV_REG; Addr <= XDFESI570_RFREQ_LSB_REG;
	     Addr++) {
		XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr,
				    1U, MuxAddr);
		XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570,
				    &Rx[Index], 1U, MuxAddr);
		Index++;
	}

	/* UnFreeze oscillator in register address (0x89=137) */
	Addr = XDFESI570_FREEZE_DCO_REG;
	Tx = XDFESI570_UNFREEZE_DCO;
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr, 1U,
			    MuxAddr);
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Tx, 1U,
			    MuxAddr);

	/* New frequency applied in register address (0x87=135) */
	Addr = XDFESI570_CONTROL_REG;
	Tx = XDFESI570_CONTROL_APPLY_FREQ;
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr, 1U,
			    MuxAddr);
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Tx, 1U,
			    MuxAddr);

	return XST_SUCCESS;
}
/****************************************************************************/
/**
*
* This function reads current state of si570, calculates parameters for si570
* MGT oscillator new frequency, writes them to si570
*
* @param CurrentFrequency is MGT oscillator current frequency.
* @param NewFrequency is MGT new frequency.
*
* @return
*	- XST_SUCCESS if successful.
*	- XST_FAILURE if failed.
*
* @note		None
*
****************************************************************************/
This function reads current state of si570, calculates parameters for si570
MGT oscillator new frequency, writes them to si570
This function reads current state of si570 calculates parameters for si570 MGT oscillator new frequency writes them to si570
u32 XDfeSi570_SetFrequency(double CurrentFrequency, double NewFrequency)
{
	const u8 XDfeSi570_HS_DIV[XDFESI570_HS_DIV_MAX_ID] = {
		4U, 5U, 6U, 7U, XDFESI570_NOT_USED, 9U, XDFESI570_NOT_USED, 11U
	};
	u8 Addr = XDFESI570_CONTROL_REG;
	u8 MuxAddr = 0x8U;
	u8 Tx = 1U;
	u8 Rx[20];
	u64 Rx_new;
	u32 Index = 0;
	u64 RFREQ;
	u64 RFREQ_new;
	double RFREQ_f;
	double f_RFREQ_new;
	u32 N;
	u32 N_new;
	u32 HS_DIV;
	double f_xtal;
	double f_dco;
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr, 1U,
			    MuxAddr);
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Tx, 1U,
			    MuxAddr);
	for (Addr = XDFESI570_N1_HS_DIV_REG; Addr <= XDFESI570_RFREQ_LSB_REG;
	     Addr++) {
		XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr,
				    1U, MuxAddr);
		XDfeSi570_I2CRdData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570,
				    &Rx[Index], 1U, MuxAddr);
		Index++;
	}
	RFREQ = (((u64)(Rx[1] & 0x3fU)) << 32U) + (Rx[2] << 24U) +
		(Rx[3] << 16U) + (Rx[4] << 8U) + Rx[5];
	RFREQ_f = (double)((double)RFREQ / (1U << 28U));
	N = (((Rx[0] & 0x1fU) << 2U) | ((Rx[1] & 0xc0U) >> 6U)) + 1U;
	HS_DIV = XDfeSi570_HS_DIV[(Rx[0] & 0xE0U) >> 5U];
	f_xtal = (CurrentFrequency * N * HS_DIV) / RFREQ_f;
	for (N_new = 1U; N_new <= XDFESI570_CLKOUT_DIVIDER_MAX; N_new++) {
		if ((N_new != 1U) && (N_new != 2U * (N_new / 2U))) {
			continue;
		}
		for (Index = 0; Index < XDFESI570_HS_DIV_MAX_ID; Index++) {
			HS_DIV = XDfeSi570_HS_DIV[Index];
			if (HS_DIV == XDFESI570_NOT_USED) {
				continue;
			}
			f_dco = NewFrequency * N_new * HS_DIV;
			if ((XDFESI570_DCO_MIN < f_dco) &&
			    (f_dco < XDFESI570_DCO_MAX)) {
				goto exit_loop;
			}
		}
		N_new += 2U;
	}
	LOG("Not available setting");
	return XST_FAILURE;
exit_loop:
	f_RFREQ_new = f_dco / f_xtal;
	RFREQ_new = (u64)(f_RFREQ_new * (1U << 28U));
	Rx_new = RFREQ_new + ((u64)(N_new - 1U) << 38U);
	for (Index = 0; Index < 6U; Index++) {
		Rx[Index] = Rx_new & 0xffU;
		Rx_new = Rx_new >> 8U;
	}
	Addr = XDFESI570_FREEZE_DCO_REG;
	Tx = XDFESI570_FREEZE_DCO;
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr, 1U,
			    MuxAddr);
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Tx, 1U,
			    MuxAddr);
	Index = 0;
	for (Addr = XDFESI570_N1_HS_DIV_REG; Addr <= XDFESI570_RFREQ_LSB_REG;
	     Addr++) {
		XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr,
				    1U, MuxAddr);
		XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570,
				    &Rx[Index], 1U, MuxAddr);
		Index++;
	}
	Addr = XDFESI570_FREEZE_DCO_REG;
	Tx = XDFESI570_UNFREEZE_DCO;
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr, 1U,
			    MuxAddr);
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Tx, 1U,
			    MuxAddr);
	Addr = XDFESI570_CONTROL_REG;
	Tx = XDFESI570_CONTROL_APPLY_FREQ;
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Addr, 1U,
			    MuxAddr);
	XDfeSi570_I2CWrData(FD_DEVICE, I2C_ADDR_I2C_MGT_SI570, &Tx, 1U,
			    MuxAddr);
	return XST_SUCCESS;
}
u32 XDfeSi570_SetFrequency ( double CurrentFrequency , double NewFrequency ) { const u8 XDfeSi570_HS_DIV [ XDFESI570_HS_DIV_MAX_ID ] = { 4U , 5U , 6U , 7U , XDFESI570_NOT_USED , 9U , XDFESI570_NOT_USED , 11U } ; u8 Addr = XDFESI570_CONTROL_REG ; u8 MuxAddr = 0x8U ; u8 Tx = 1U ; u8 Rx [ 20 ] ; u64 Rx_new ; u32 Index = 0 ; u64 RFREQ ; u64 RFREQ_new ; double RFREQ_f ; double f_RFREQ_new ; u32 N ; u32 N_new ; u32 HS_DIV ; double f_xtal ; double f_dco ; XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Addr , 1U , MuxAddr ) ; XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Tx , 1U , MuxAddr ) ; for ( Addr = XDFESI570_N1_HS_DIV_REG ; Addr <= XDFESI570_RFREQ_LSB_REG ; Addr ++ ) { XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Addr , 1U , MuxAddr ) ; XDfeSi570_I2CRdData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Rx [ Index ] , 1U , MuxAddr ) ; Index ++ ; } RFREQ = ( ( ( u64 ) ( Rx [ 1 ] & 0x3fU ) ) << 32U ) + ( Rx [ 2 ] << 24U ) + ( Rx [ 3 ] << 16U ) + ( Rx [ 4 ] << 8U ) + Rx [ 5 ] ; RFREQ_f = ( double ) ( ( double ) RFREQ / ( 1U << 28U ) ) ; N = ( ( ( Rx [ 0 ] & 0x1fU ) << 2U ) | ( ( Rx [ 1 ] & 0xc0U ) >> 6U ) ) + 1U ; HS_DIV = XDfeSi570_HS_DIV [ ( Rx [ 0 ] & 0xE0U ) >> 5U ] ; f_xtal = ( CurrentFrequency * N * HS_DIV ) / RFREQ_f ; for ( N_new = 1U ; N_new <= XDFESI570_CLKOUT_DIVIDER_MAX ; N_new ++ ) { if ( ( N_new != 1U ) && ( N_new != 2U * ( N_new / 2U ) ) ) { continue ; } for ( Index = 0 ; Index < XDFESI570_HS_DIV_MAX_ID ; Index ++ ) { HS_DIV = XDfeSi570_HS_DIV [ Index ] ; if ( HS_DIV == XDFESI570_NOT_USED ) { continue ; } f_dco = NewFrequency * N_new * HS_DIV ; if ( ( XDFESI570_DCO_MIN < f_dco ) && ( f_dco < XDFESI570_DCO_MAX ) ) { goto exit_loop ; } } N_new += 2U ; } LOG ( " " ) ; return XST_FAILURE ; exit_loop : f_RFREQ_new = f_dco / f_xtal ; RFREQ_new = ( u64 ) ( f_RFREQ_new * ( 1U << 28U ) ) ; Rx_new = RFREQ_new + ( ( u64 ) ( N_new - 1U ) << 38U ) ; for ( Index = 0 ; Index < 6U ; Index ++ ) { Rx [ Index ] = Rx_new & 0xffU ; Rx_new = Rx_new >> 8U ; } Addr = XDFESI570_FREEZE_DCO_REG ; Tx = XDFESI570_FREEZE_DCO ; XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Addr , 1U , MuxAddr ) ; XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Tx , 1U , MuxAddr ) ; Index = 0 ; for ( Addr = XDFESI570_N1_HS_DIV_REG ; Addr <= XDFESI570_RFREQ_LSB_REG ; Addr ++ ) { XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Addr , 1U , MuxAddr ) ; XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Rx [ Index ] , 1U , MuxAddr ) ; Index ++ ; } Addr = XDFESI570_FREEZE_DCO_REG ; Tx = XDFESI570_UNFREEZE_DCO ; XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Addr , 1U , MuxAddr ) ; XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Tx , 1U , MuxAddr ) ; Addr = XDFESI570_CONTROL_REG ; Tx = XDFESI570_CONTROL_APPLY_FREQ ; XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Addr , 1U , MuxAddr ) ; XDfeSi570_I2CWrData ( FD_DEVICE , I2C_ADDR_I2C_MGT_SI570 , & Tx , 1U , MuxAddr ) ; return XST_SUCCESS ; }
This function reads current state of si570, calculates parameters for si570
MGT oscillator new frequency, writes them to si570
This function reads current state of si570 calculates parameters for si570 MGT oscillator new frequency writes them to si570
/* Set a control register address (0x87=135) and set recall NVM to RAM */ /* Set a si570 register address and read data */ /* Prepare parameters for calculation */ /* Search N and HS_DIV to be in range [4.85GHz,5.67GHz] */ /* valid are all even numbers and 1 */ /* Find RFREQ for the chosen N and HS_DIV */ /* Sort RFREQ into u8 array */ /* Freeze oscillator in register address (0x89=137) */ /* Set a si570 register address and write data */ /* UnFreeze oscillator in register address (0x89=137) */ /* New frequency applied in register address (0x87=135) */