#include <stdio.h>
#include <stdlib.h>

#define SIZE_DATASET 1024
#define PI 3.14159

void sine_int(int *result, unsigned int size);

const char* file_1 = "C:\\tmp\\output1.dat";
const char* file_2 = "C:\\tmp\\output2.dat";

int results1[SIZE_DATASET];
int results2[SIZE_DATASET];

unsigned int count = 0;

volatile int return_code = 0;
volatile int answer;

/* Beginning of SARAM memory */
#pragma DATA_SECTION(saram_start, ".saram")
unsigned int saram_start[(SIZE_DATASET * 2)];

int main(void)
{
	FILE *openfile_1;
	FILE *openfile_2;
	unsigned int *copy_destination;
	unsigned int file_size;

	/* Initialize the destination pointer */
	copy_destination = saram_start;
	
	/* Perform a read test on the output files */
	/* Should fail when running for the first time */
	openfile_1 = fopen(file_1, "rb");
	if (openfile_1 == NULL)
		printf("Error opening %s for reading\n", file_1);

	openfile_2 = fopen(file_2, "rb");
	if (openfile_2 == NULL)
		printf("Error opening %s for reading\n", file_2);

	/* Create the two output files */
	freopen(file_1, "wb+", openfile_1);
	if (openfile_1 == NULL)
		printf("Error opening %s\n", file_1);
	
	freopen(file_2, "wb+", openfile_2);
	if (openfile_2 == NULL)
		printf("Error opening %s\n", file_2);
	
	/* Initialize data structures */
	for (count = 0; count < SIZE_DATASET; count++)
	{
		results1[count] = 0;
		results2[count] = 0;
	}
	/* Initialize the memory destination */
	for (count = 0; count < (SIZE_DATASET * 2); count++)
	{
		copy_destination[count] = 0;
	}
	
	sine_int(results1, SIZE_DATASET);
	sine_int(results2, SIZE_DATASET);

	/* Write to the output files */
	return_code = fwrite(&results1, sizeof(int), SIZE_DATASET, openfile_1); 
	if (return_code < SIZE_DATASET)
		printf("Error in writing to file: %d bytes were written to %s\n", return_code, file_1);
	return_code = fwrite(&results2, sizeof(int), SIZE_DATASET, openfile_2); 
	if (return_code < SIZE_DATASET)
		printf("Error in writing to file: %d bytes were written to %s\n", return_code, file_2);

	/* Make sure all data is written to the disk before continuing */ 
	fflush(openfile_1);
	fflush(openfile_2);

	/* Get the size of the first output file */
	fseek(openfile_1, 0, SEEK_END);
	file_size = ftell(openfile_1);
	rewind(openfile_1);

	/* Read the contents to the first file to SARAM1 */
	return_code = fread(copy_destination, sizeof(int), file_size, openfile_1);
	if (return_code < (file_size / sizeof(int)))
		printf("Error in reading file: %d bytes were written to address 0x%x\n", return_code, copy_destination);

	/* Byte-by-byte comparison routine */
	rewind(openfile_1);
	copy_destination = saram_start;
	for (count = 0; count < (file_size / sizeof(int)); count++)
	{
		 unsigned int comparison_value;
		 fread(&comparison_value, sizeof(int), 1, openfile_1);
		 if(copy_destination[count] != comparison_value)
		 	printf("Comparison failed in byte 0x%x!\n", count);
	}

	/* Get the size of the second output file */	
	fseek(openfile_2, 0, SEEK_END);
	file_size = ftell(openfile_2);
	rewind(openfile_2);
	
	/* Increment the destination address by 4096 */
	copy_destination += (file_size / sizeof(int));
	
	/* Read the contents to the second file to SARAM1 */
	return_code = fread(copy_destination, sizeof(int), file_size, openfile_2);
	if (return_code < (file_size / sizeof(int)))
		printf("Error in reading file: %d bytes were written to address 0x%x\n", return_code, copy_destination);
	
	/* Byte-by-byte comparison routine */
	rewind(openfile_2);
	for (count = 0; count < (file_size / sizeof(int)); count++)
	{
		 unsigned int comparison_value;
		 fread(&comparison_value, sizeof(int), 1, openfile_2);
		 if(copy_destination[count] != comparison_value)
		 	printf("Comparison failed in byte 0x%x!\n", count);
	}

	/* Put a breakpoint here to inspect the memory... */
	asm("  NOP");

	/* Close the files */
	fclose(openfile_1);
	fclose(openfile_2);

	/* Simple I/O operation with user keyboard input */ 
	printf("Please input a number: ");
	scanf("%d", &answer);
	return_code = printf(" %d\n", answer);
	
	/* Make sure all data is printed out before exiting... */
	fflush(stdout);
	
	/* Return to system */
	return return_code;
}

void sine_int(int *result, unsigned int size)
{
	unsigned int counter = 0;
	const short A=0x7e66; /* A=(1.975/2 * 32768) */
	short y[3]={0,0x1209,0}; /* (y0,y1,y2), y1=(0.1409*32768) */
	for (counter = 0; counter < size; counter++)
	{
		y[0] = (((A*y[1])>>15) + ((A*y[1])>>15)) - y[2];
		y[2] = y[1]; /* y2 <–– y1 */
		y[1] = y[0]; /* y1 <–– y0 */
		result[counter] = y[2];
	}
}

