/***********************************************************************************************
 * Company: MicroSemi Corporation
 *
 * File: main.c
 * File history:
 * Revision:
 *
 * Description:recieves the user entered option,address and data through MMUAT interface and sends the data to FPGA fabric.
 *  Recieves the data from FPGA fabric and sends back through MMUART interface.
 *
 * SmartFusion2: SF2 MDDR Demo
 *
 * Author: Applications Engineering
 *
 ************************************************************************************************/
#include <stdio.h>
#include <math.h>


#include "drivers/mss_uart/mss_uart.h"
#define SRAM_BASE_ADDR 0x30000000
#define DDR_BASE_ADDR  0xA0000000



uint8_t UARTMsgTx2[8];
uint8_t UARTMsgTx3[2048];

//     uint8_t input_buffer[2048];

uint32_t output_buffer_burst[512];
uint32_t output_buffer_single[2];



static void Reader(void);
//void *memcpy(void *dest, void *src, size_t count);
void * memset ( void * ptr, int value, size_t num );


size_t
UART_Polled_Rx
(
		mss_uart_instance_t * this_uart,
		uint8_t * rx_buff,
		size_t buff_size
)
{
	size_t rx_size = 0U;

	while( rx_size < buff_size )
	{
		while ( ((this_uart->hw_reg->LSR) & 0x1) != 0U  )
		{
			rx_buff[rx_size] = this_uart->hw_reg->RBR;
			++rx_size;
		}
	}

	return rx_size;
}

/* Function for delay */
void delay ( volatile uint32_t n)
{
	while(n!=0)
	{
		n--;
	}
}

uint8_t rx_buff[1];
/*-------------------------------------------------------------------------*//**
 * main() function.
 */
int main()
{


	MSS_UART_init( &g_mss_uart1, MSS_UART_115200_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );


	while (1)
	{
		Reader ();
	}

}
/*-------------------------------------------------------------------------*/

//***************************************************************

static void Reader(void)
{
	//  size_t rx_size;

	uint32_t output_buffer1;

	uint16_t  i,j;
	uint8_t user_option,Address_option[4],data_option[8];
	uint32_t option_32bit,address_32bit,data_32bit[2];


	volatile uint32_t *fab_sram_word_ptr;

	///////////////////////////////////////////////////
	while(!(UART_Polled_Rx ( &g_mss_uart1, (uint8_t *) &user_option, 1 )));

	MSS_UART_polled_tx( &g_mss_uart1, (const uint8_t *)"a", 1 );

	while(!(UART_Polled_Rx ( &g_mss_uart1,  (uint8_t *) &Address_option, 4 )));

	MSS_UART_polled_tx( &g_mss_uart1, (const uint8_t *)"d", 1 );

	if((user_option == '1' )||( user_option == '3'))
	{

		while(!(UART_Polled_Rx ( &g_mss_uart1,(uint8_t *) &data_option, 8 )));

	}


	option_32bit = user_option;

	address_32bit = (uint32_t)(Address_option[3] | Address_option[2] << 8 | Address_option[1] << 16 |  Address_option[0] << 24);

	data_32bit[0] = (uint32_t)(data_option[3] | data_option[2] << 8 | data_option[1] << 16 | data_option[0] << 24 ) ;

	data_32bit[1] = (uint32_t)(data_option[7] | data_option[6] << 8 | data_option[5] << 16 | data_option[4] << 24 ) ;



	///////////////////////////////////  option_address_data write - SRAM ////////////////////////////////////


	fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;
	delay(100);

	//Write option sample to SRAM
	output_buffer1 = ((uint32_t)option_32bit);
	*fab_sram_word_ptr = output_buffer1;
	 fab_sram_word_ptr = fab_sram_word_ptr + 1;
	delay(100);

	//Write address sample to SRAM
	output_buffer1 = ((uint32_t)address_32bit);
	*fab_sram_word_ptr = output_buffer1;
	 fab_sram_word_ptr = fab_sram_word_ptr + 1;
	delay(100);


	//Write data_lower32bit sample to SRAM
	output_buffer1 = ((uint32_t)data_32bit[0]);
	*fab_sram_word_ptr = output_buffer1;
	 fab_sram_word_ptr = fab_sram_word_ptr + 1;

	delay(100);
	//Write data_upper32bit sample to SRAM
	output_buffer1 = ((uint32_t)data_32bit[1]);
	*fab_sram_word_ptr = output_buffer1;
	 fab_sram_word_ptr = fab_sram_word_ptr + 1;

	delay(100);

	delay(10000);


		if (user_option == '2')
		{
			delay(400);
			fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;

			  fab_sram_word_ptr = fab_sram_word_ptr + 4;

			for( i = 0; i<2; i++)
			{
				delay(40);
				output_buffer_single[i] = *fab_sram_word_ptr;
				fab_sram_word_ptr = fab_sram_word_ptr + 1;

			}

			delay(400);
			i= 0;
			j=0;

			UARTMsgTx2[0]   = output_buffer_single[1]>>24;
			UARTMsgTx2[1] = output_buffer_single[1]>>16;
			UARTMsgTx2[2]   = output_buffer_single[1]>>8;
			UARTMsgTx2[3] = output_buffer_single[1] ;

			UARTMsgTx2[4]   = output_buffer_single[0]>>24;
			UARTMsgTx2[5] = output_buffer_single[0]>>16 ;
			UARTMsgTx2[6]   = output_buffer_single[0]>>8;
			UARTMsgTx2[7] = output_buffer_single[0] ;


			delay(400);
			MSS_UART_polled_tx(&g_mss_uart1,(uint8_t *)&UARTMsgTx2,8);


		}
		else if (user_option == '4')

		{
			delay(400);
			fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;
			fab_sram_word_ptr = fab_sram_word_ptr + 4;
			for( i = 0; i< 512; i++)
			{
				delay(40);
				output_buffer_burst[i] = *fab_sram_word_ptr;
				fab_sram_word_ptr = fab_sram_word_ptr + 1;
			}


			i=0;

			for (j = 0; j < 512; j = j+2)
			{
				UARTMsgTx3[i+7]   = output_buffer_burst[j+1]>>24;
				UARTMsgTx3[i+6] = output_buffer_burst[j+1]>>16;
				UARTMsgTx3[i+5] = output_buffer_burst[j+1]>>8;
				UARTMsgTx3[i+4] = output_buffer_burst[j+1];
				UARTMsgTx3[i+3]   = output_buffer_burst[j]>>24;
				UARTMsgTx3[i+2] = output_buffer_burst[j]>>16;
				UARTMsgTx3[i+1] = output_buffer_burst[j]>>8;
				UARTMsgTx3[i+0] = output_buffer_burst[j];

				i = i+8;
			}


			delay(400);
			MSS_UART_polled_tx( &g_mss_uart1, (const uint8_t *)"c", 1 );
			delay(40);
			MSS_UART_polled_tx(&g_mss_uart1,(uint8_t *)&UARTMsgTx3,2048);
		}


	j = 0;
	i = 0;


	memset(UARTMsgTx2,0,sizeof (UARTMsgTx2));
	memset(UARTMsgTx3,0,sizeof (UARTMsgTx3));

	memset(output_buffer_single,0,sizeof (output_buffer_single));
	memset(output_buffer_burst,0,sizeof (output_buffer_burst));

	return;
}
