XilinxProcessorIPLib/drivers/v_sdirxss/examples/xuhdsdi_rx_example/si5324drv.c
int Si5324_FindN2ls(si5324_settings_t *settings) {
	u32 result = 0;
	u64 f3_actual;
	u64 fosc_actual;
	u64 fout_actual;
	u64 delta_fout;
	u64 n2_ls_div_n3;
	u32 mult;

	n2_ls_div_n3 = settings->fosc / (settings->fin >> 28) / settings->n2_hs / 2;
	Si5324_RatApprox(n2_ls_div_n3,
			settings->n3_max,
			&(settings->n2_ls),
			&(settings->n3));
	settings->n2_ls *= 2;

	/*
	 * Rational approximation returns the smalles ratio possible.
	 * Upscaling might be needed when when one or both of the
	 * numbers are too low.
	 */
	if (settings->n2_ls < settings->n2_ls_min) {
		mult =  settings->n2_ls_min / settings->n2_ls;
		mult = (settings->n2_ls_min % settings->n2_ls) ? mult + 1 : mult;
		settings->n2_ls *= mult;
		settings->n3    *= mult;
	}
	if (settings->n3 < settings->n3_min) {
		mult =  settings->n3_min / settings->n3;
		mult = (settings->n3_min % settings->n3) ? mult + 1 : mult;
		settings->n2_ls *= mult;
		settings->n3    *= mult;
	}
	if (SI5324_DEBUG) {
		xil_printf("\t\t\tTrying N2_LS = %d N3 = %d.\n", settings->n2_ls, settings->n3);
	}
	/* Check if N2_LS and N3 are within the required ranges */
	if ((settings->n2_ls < settings->n2_ls_min) ||
			(settings->n2_ls > settings->n2_ls_max)) {
		xil_printf("\t\t\tN2_LS out of range.\n");
	} else if ((settings->n3 < settings->n3_min) ||
			(settings->n3 > settings->n3_max)) {
		xil_printf("\t\t\tN3 out of range.\n");
	}
	else {
		/*
		 * N2_LS and N3 values within range:
		 * check actual output frequency
		 */
		f3_actual = settings->fin / settings->n3;
		fosc_actual = f3_actual * settings->n2_hs * settings->n2_ls;
		fout_actual = fosc_actual / (settings->n1_hs * settings->nc_ls);
		delta_fout = fout_actual - settings->fout;
		/* Check actual frequencies for validity */
		if ((f3_actual < ((u64)SI5324_F3_MIN) << 28) ||
				(f3_actual > ((u64)SI5324_F3_MAX) << 28)) {
			if (SI5324_DEBUG) {
				xil_printf("\t\t\tF3 frequency out of range.\n");
			}
		} else if ((fosc_actual < ((u64)SI5324_FOSC_MIN) << 28) ||
				(fosc_actual > ((u64)SI5324_FOSC_MAX) << 28)) {
			if (SI5324_DEBUG) {
				xil_printf("\t\t\tFosc frequency out of range.\n");
			}
		} else if ((fout_actual < ((u64)SI5324_FOUT_MIN) << 28) ||
				(fout_actual >((u64)SI5324_FOUT_MAX) << 28)) {
			if (SI5324_DEBUG) {
				xil_printf("\t\t\tFout frequency out of range.\n");
			}
		} else {
			if (SI5324_DEBUG) {
				xil_printf("\t\t\tFound solution: "
						"fout = %dHz delta = %dHz.\n",
						(u32)(fout_actual >> 28),
						(u32)(delta_fout >> 28));
				xil_printf("\t\t\t                "
						"fosc = %dkHz f3 = %dHz.\n",
						(u32)((fosc_actual >> 28) / 1000),
						(u32)(f3_actual >> 28));
			}
			if (((u64)llabs(delta_fout)) < settings->best_delta_fout) {
				/* Found a better solution: remember this one! */
				if (SI5324_DEBUG) {
					xil_printf("\t\t\tThis solution is the best yet!\n");
				}
				settings->best_n1_hs = settings->n1_hs;
				settings->best_nc_ls = settings->nc_ls;
				settings->best_n2_hs = settings->n2_hs;
				settings->best_n2_ls = settings->n2_ls;
				settings->best_n3 = settings->n3;
				settings->best_fout = fout_actual;
				settings->best_delta_fout = llabs(delta_fout);
				if (delta_fout == 0) {
					/*
					 * Best possible result found.
					 * Skip the rest of the possibilities.
					 */
					result = 1;
				}
			}
		}
	}
	return result;
}
/*****************************************************************************/
/**
 * Search through the possible settings for the N2_LS parameter. Finds the best
 * setting for N2_LS and N3n with the values for N1_HS, NCn_LS, and N2_HS
 * already set in settings.
 *
 * @param	settings Holds the settings up till now.
 * @return	1 when the best possible result has been found.
 * @note	Private function.
 */
Search through the possible settings for the N2_LS parameter. Finds the best
setting for N2_LS and N3n with the values for N1_HS, NCn_LS, and N2_HS
already set in settings.

@param       settings Holds the settings up till now.
@return      1 when the best possible result has been found.
@note        Private function.
Search through the possible settings for the N2_LS parameter . Finds the best setting for N2_LS and N3n with the values for N1_HS NCn_LS and N2_HS already set in settings . @param settings Holds the settings up till now . @return 1 when the best possible result has been found . @note Private function .
int Si5324_FindN2ls(si5324_settings_t *settings) {
	u32 result = 0;
	u64 f3_actual;
	u64 fosc_actual;
	u64 fout_actual;
	u64 delta_fout;
	u64 n2_ls_div_n3;
	u32 mult;
	n2_ls_div_n3 = settings->fosc / (settings->fin >> 28) / settings->n2_hs / 2;
	Si5324_RatApprox(n2_ls_div_n3,
			settings->n3_max,
			&(settings->n2_ls),
			&(settings->n3));
	settings->n2_ls *= 2;
	if (settings->n2_ls < settings->n2_ls_min) {
		mult =  settings->n2_ls_min / settings->n2_ls;
		mult = (settings->n2_ls_min % settings->n2_ls) ? mult + 1 : mult;
		settings->n2_ls *= mult;
		settings->n3    *= mult;
	}
	if (settings->n3 < settings->n3_min) {
		mult =  settings->n3_min / settings->n3;
		mult = (settings->n3_min % settings->n3) ? mult + 1 : mult;
		settings->n2_ls *= mult;
		settings->n3    *= mult;
	}
	if (SI5324_DEBUG) {
		xil_printf("\t\t\tTrying N2_LS = %d N3 = %d.\n", settings->n2_ls, settings->n3);
	}
	if ((settings->n2_ls < settings->n2_ls_min) ||
			(settings->n2_ls > settings->n2_ls_max)) {
		xil_printf("\t\t\tN2_LS out of range.\n");
	} else if ((settings->n3 < settings->n3_min) ||
			(settings->n3 > settings->n3_max)) {
		xil_printf("\t\t\tN3 out of range.\n");
	}
	else {
		f3_actual = settings->fin / settings->n3;
		fosc_actual = f3_actual * settings->n2_hs * settings->n2_ls;
		fout_actual = fosc_actual / (settings->n1_hs * settings->nc_ls);
		delta_fout = fout_actual - settings->fout;
		if ((f3_actual < ((u64)SI5324_F3_MIN) << 28) ||
				(f3_actual > ((u64)SI5324_F3_MAX) << 28)) {
			if (SI5324_DEBUG) {
				xil_printf("\t\t\tF3 frequency out of range.\n");
			}
		} else if ((fosc_actual < ((u64)SI5324_FOSC_MIN) << 28) ||
				(fosc_actual > ((u64)SI5324_FOSC_MAX) << 28)) {
			if (SI5324_DEBUG) {
				xil_printf("\t\t\tFosc frequency out of range.\n");
			}
		} else if ((fout_actual < ((u64)SI5324_FOUT_MIN) << 28) ||
				(fout_actual >((u64)SI5324_FOUT_MAX) << 28)) {
			if (SI5324_DEBUG) {
				xil_printf("\t\t\tFout frequency out of range.\n");
			}
		} else {
			if (SI5324_DEBUG) {
				xil_printf("\t\t\tFound solution: "
						"fout = %dHz delta = %dHz.\n",
						(u32)(fout_actual >> 28),
						(u32)(delta_fout >> 28));
				xil_printf("\t\t\t                "
						"fosc = %dkHz f3 = %dHz.\n",
						(u32)((fosc_actual >> 28) / 1000),
						(u32)(f3_actual >> 28));
			}
			if (((u64)llabs(delta_fout)) < settings->best_delta_fout) {
				if (SI5324_DEBUG) {
					xil_printf("\t\t\tThis solution is the best yet!\n");
				}
				settings->best_n1_hs = settings->n1_hs;
				settings->best_nc_ls = settings->nc_ls;
				settings->best_n2_hs = settings->n2_hs;
				settings->best_n2_ls = settings->n2_ls;
				settings->best_n3 = settings->n3;
				settings->best_fout = fout_actual;
				settings->best_delta_fout = llabs(delta_fout);
				if (delta_fout == 0) {
					result = 1;
				}
			}
		}
	}
	return result;
}
int Si5324_FindN2ls ( si5324_settings_t * settings ) { u32 result = 0 ; u64 f3_actual ; u64 fosc_actual ; u64 fout_actual ; u64 delta_fout ; u64 n2_ls_div_n3 ; u32 mult ; n2_ls_div_n3 = settings -> fosc / ( settings -> fin >> 28 ) / settings -> n2_hs / 2 ; Si5324_RatApprox ( n2_ls_div_n3 , settings -> n3_max , & ( settings -> n2_ls ) , & ( settings -> n3 ) ) ; settings -> n2_ls *= 2 ; if ( settings -> n2_ls < settings -> n2_ls_min ) { mult = settings -> n2_ls_min / settings -> n2_ls ; mult = ( settings -> n2_ls_min % settings -> n2_ls ) ? mult + 1 : mult ; settings -> n2_ls *= mult ; settings -> n3 *= mult ; } if ( settings -> n3 < settings -> n3_min ) { mult = settings -> n3_min / settings -> n3 ; mult = ( settings -> n3_min % settings -> n3 ) ? mult + 1 : mult ; settings -> n2_ls *= mult ; settings -> n3 *= mult ; } if ( SI5324_DEBUG ) { xil_printf ( " \t \t \t \n " , settings -> n2_ls , settings -> n3 ) ; } if ( ( settings -> n2_ls < settings -> n2_ls_min ) || ( settings -> n2_ls > settings -> n2_ls_max ) ) { xil_printf ( " \t \t \t \n " ) ; } else if ( ( settings -> n3 < settings -> n3_min ) || ( settings -> n3 > settings -> n3_max ) ) { xil_printf ( " \t \t \t \n " ) ; } else { f3_actual = settings -> fin / settings -> n3 ; fosc_actual = f3_actual * settings -> n2_hs * settings -> n2_ls ; fout_actual = fosc_actual / ( settings -> n1_hs * settings -> nc_ls ) ; delta_fout = fout_actual - settings -> fout ; if ( ( f3_actual < ( ( u64 ) SI5324_F3_MIN ) << 28 ) || ( f3_actual > ( ( u64 ) SI5324_F3_MAX ) << 28 ) ) { if ( SI5324_DEBUG ) { xil_printf ( " \t \t \t \n " ) ; } } else if ( ( fosc_actual < ( ( u64 ) SI5324_FOSC_MIN ) << 28 ) || ( fosc_actual > ( ( u64 ) SI5324_FOSC_MAX ) << 28 ) ) { if ( SI5324_DEBUG ) { xil_printf ( " \t \t \t \n " ) ; } } else if ( ( fout_actual < ( ( u64 ) SI5324_FOUT_MIN ) << 28 ) || ( fout_actual > ( ( u64 ) SI5324_FOUT_MAX ) << 28 ) ) { if ( SI5324_DEBUG ) { xil_printf ( " \t \t \t \n " ) ; } } else { if ( SI5324_DEBUG ) { xil_printf ( " \t \t \t " " \n " , ( u32 ) ( fout_actual >> 28 ) , ( u32 ) ( delta_fout >> 28 ) ) ; xil_printf ( " \t \t \t " " \n " , ( u32 ) ( ( fosc_actual >> 28 ) / 1000 ) , ( u32 ) ( f3_actual >> 28 ) ) ; } if ( ( ( u64 ) llabs ( delta_fout ) ) < settings -> best_delta_fout ) { if ( SI5324_DEBUG ) { xil_printf ( " \t \t \t \n " ) ; } settings -> best_n1_hs = settings -> n1_hs ; settings -> best_nc_ls = settings -> nc_ls ; settings -> best_n2_hs = settings -> n2_hs ; settings -> best_n2_ls = settings -> n2_ls ; settings -> best_n3 = settings -> n3 ; settings -> best_fout = fout_actual ; settings -> best_delta_fout = llabs ( delta_fout ) ; if ( delta_fout == 0 ) { result = 1 ; } } } } return result ; }
Search through the possible settings for the N2_LS parameter.
Search through the possible settings for the N2_LS parameter .
/*
	 * Rational approximation returns the smalles ratio possible.
	 * Upscaling might be needed when when one or both of the
	 * numbers are too low.
	 */ /* Check if N2_LS and N3 are within the required ranges */ /*
		 * N2_LS and N3 values within range:
		 * check actual output frequency
		 */ /* Check actual frequencies for validity */ /* Found a better solution: remember this one! */ /*
					 * Best possible result found.
					 * Skip the rest of the possibilities.
					 */