/*
 * Calculate the incremental resolution for the Arbitary Function Generator.
 * This version uses the "improved" method.
 * Written by Ben Low, Copyright 1996. Permission is granted to reproduce this
 * algorithm and/or code in full or part, provided acknowldegment is given.
 */

#include <stdio.h>

/* change to non-zero to get a complete output, otherwise I'll just print
 *  the output frequency and percentage increase.
 */
#define FULLOUTPUT 0

/* size of the static RAM */
#define RAMSIZE 32768

double clocks[] = {7812.5, 250e3, 2e6};	/* clocks derived from main clock */
int nclocks = sizeof(clocks) / sizeof(clocks[0]);


main()
{
	int i;
	long L, k, endk, endL;
	double N, fout, fprev, df, max_df = 0.0;

	for (i=0; i < nclocks; i++)
	{
		fprev = clocks[i]/RAMSIZE;	/* calc. first fout, to use in initial df */

		k = 1;	/* start with 1 period in waveform (ie. minimum freq) */

		/* stop when it's time to switch to the next clock, or if
		   we're on the last clock stop arbitrarily at RAMSIZE/16. */
		endk = (i < (nclocks - 1)) ? (clocks[i] / clocks[i+1]) : (RAMSIZE/16);

		do
		{
			L = RAMSIZE;	/* start with max. waveform length (fully fill RAM) */

			endL = RAMSIZE * k/(k+1);

			do
			{
				N = (double) L / (double) k;	/* length of one period (real number) */

				fout = clocks[i] / N;				/* output frequency */

				df = (fout - fprev) / fout;		/* relative increment */

				#if FULLOUTPUT != 0
	 				fprintf(stdout, "%8.1lf %5ld %4ld %8.1lf %8.2lf %8.4lf\n",
						clocks[i], L, k, N, fout, df*100);
				#else
	 				fprintf(stdout, "%8.6lg\t%8.4lf\n", fout, df*100);
				#endif

				fprev = fout;

				if (df > max_df)
				{
					max_df = df;
				}

				L--;	/* try the next smaller waveform length */

			} while (L > endL );

			fprintf(stderr, "k = %ld, max_df = %.3lf %%\n", k, max_df*100);

			k++;

		} while (k < endk);
	}

}
