/***********************************************************************************************
* Company: MicroSemi Corporation
*
* File: main.c
* File history:
* Revision:       1.0 Date: 7 Feb 2013  Initial release.
*                 2.0 Date: 29 July 2013 11.1 SP1 Update.
*
*
* Description:Loads the filter coefficients and filter input data using UART interface
* and reads the filtered data and its FFT values.
*
* SmartFusion2: FIR FILTER DEMO
*
* Author: Applications Engineering
*
************************************************************************************************/
#include <stdio.h>
#include <math.h>
#include "mss_uart.h"
#include "mss_gpio.h"
#define SRAM_BASE_ADDR 0x30000000


    uint8_t UARTMsgTx1[2048];
    uint8_t UARTMsgTx2[2048];
    uint8_t UARTMsgTx3[2048];
    uint8_t img_buffer[256];
       uint8_t input_buffer[2048];
       uint16_t output_buffer[2048];
       uint16_t output_buffer2[2048];
       uint16_t output_buffer3[512];


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 );

	  MSS_GPIO_init();
	  MSS_GPIO_config( MSS_GPIO_0, MSS_GPIO_OUTPUT_MODE  );
	  MSS_GPIO_config( MSS_GPIO_1, MSS_GPIO_OUTPUT_MODE  );
	  MSS_GPIO_config( MSS_GPIO_2, MSS_GPIO_OUTPUT_MODE  );

	  while (1)
	    {
		  Reader ();
	    }

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

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

static void Reader(void)
{
    size_t rx_size;

    uint16_t output_buffer1;
    int32_t img_size,ii,length;

    uint16_t  i,j;
    uint8_t Coefficient[64];


    uint32_t *fab_sram_word_ptr;

    while(!(UART_Polled_Rx ( &g_mss_uart1, rx_buff, 1 )));
    if(rx_buff[0] == 'h')
        MSS_UART_polled_tx( &g_mss_uart1, (const uint8_t *)"a", 1 );

    while(!(UART_Polled_Rx ( &g_mss_uart1, rx_buff, 1 )))
         ;

    if(rx_buff[0] == 'n')
        MSS_UART_polled_tx( &g_mss_uart1, (const uint8_t *)"d", 1 );

    while(!(UART_Polled_Rx ( &g_mss_uart1, rx_buff, 1 )))
         ;

    if(rx_buff[0] == 's')
        MSS_UART_polled_tx( &g_mss_uart1, (const uint8_t *)"h", 1 );

    while(!(UART_Polled_Rx ( &g_mss_uart1, rx_buff, 1 )))
         ;

    if(rx_buff[0] == 'a')
        MSS_UART_polled_tx( &g_mss_uart1, (const uint8_t *)"k", 1 );

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



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

    ii = 0;
    while(img_size > 0)
    {
        rx_size =0;
        if (img_size >=256)
        {
            length = 256;
        }
        else
        {
            length = img_size;
        }

        do
        {
            rx_size = UART_Polled_Rx(&g_mss_uart1, (uint8_t *)&img_buffer, length);
        }
        while(!rx_size);

        if(rx_size != length)
        {
            return;
        }
        img_size -= length;
          /* Aligning to 32 bit */
        if ((length%4) != 0)
        {
            length += (4-(length%4));
        }
        memcpy((uint8_t *)&input_buffer+ii,(uint8_t *)&img_buffer, length);
        ii += length;
        MSS_UART_polled_tx(&g_mss_uart1,(const uint8_t *)"p",1);

    }

    while( ! UART_Polled_Rx(&g_mss_uart1, (uint8_t *)&Coefficient, 32));//64



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

        MSS_GPIO_set_output(MSS_GPIO_0, 0);
        MSS_GPIO_set_output(MSS_GPIO_1, 1);
        MSS_GPIO_set_output(MSS_GPIO_2, 1);

        ///////////////////////////////////  COEF -  SRAM WRITE ////////////////////////////////////

               fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;
               for( i = 0; i< 32; i=i+2)//64
               {
       			//Write each sample to SRAM
               	 output_buffer1 = ((uint16_t)Coefficient[i]<<8) + Coefficient[i+1];
               	 *fab_sram_word_ptr = output_buffer1;
                  fab_sram_word_ptr = fab_sram_word_ptr + 1;
               	}

              	 delay(1000);
              	MSS_GPIO_set_output(MSS_GPIO_2, 0);
 ///////////////////////////////////  INPUT SIGNAL - SRAM WRITE ////////////////////////////////////

        fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;
        for( i = 0; i< 2048; i=i+2)
        {
			//Write each sample to SRAM
        	 output_buffer1 = ((uint16_t)input_buffer[i]<<8) + input_buffer[i+1];
        	 *fab_sram_word_ptr = output_buffer1;
         	  fab_sram_word_ptr = fab_sram_word_ptr + 1;
        	}

       	 delay(10000);
       	MSS_GPIO_set_output(MSS_GPIO_2, 1);

        fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;
    	  for( i = 0; i< 256; i++)
        		  {
    						//read  16 bit  from  SRAM
     				 output_buffer[i] = *fab_sram_word_ptr;
    				 delay(10);
    			     fab_sram_word_ptr = fab_sram_word_ptr + 1;
       		  		}


              MSS_GPIO_set_output(MSS_GPIO_0, 1);
              MSS_GPIO_set_output(MSS_GPIO_1, 0);

             fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;

            		  for( i = 0; i< 256; i++)
             		  {

             						//read  16 bit  from  SRAM
             						 output_buffer3[i] = *fab_sram_word_ptr;
             						 delay(10);
              					    fab_sram_word_ptr = fab_sram_word_ptr + 1;
             		  		}



              MSS_GPIO_set_output(MSS_GPIO_0, 0);
       		  MSS_GPIO_set_output(MSS_GPIO_1, 0);
       		  fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;

      		  for( i = 0; i< 1024; i++)
        		  {

        						//read  16 bit  from  SRAM
        						 output_buffer2[i] = *fab_sram_word_ptr;
        						 delay(10);
         					    fab_sram_word_ptr = fab_sram_word_ptr + 1;
        		  		}


         		MSS_GPIO_set_output(MSS_GPIO_0, 1);
         		MSS_GPIO_set_output(MSS_GPIO_1, 1);


         		  j = 0;
         		  i = 0;
       	        //for (i = 0; i < 512; i =  i + 2)
         		while(i<512)
       	        {
       	        	UARTMsgTx2[i]   = output_buffer[j]>>8;
       	        	UARTMsgTx2[i+1] = output_buffer[j];
       	        	j = j + 1;
       	        	i = i + 2;
       	        }

       	        j = 0;
       	        for (i = 0; i < 2048; i =  i + 2)
       	        {
       	        	UARTMsgTx1[i]   = output_buffer2[j]>>8;
       	        	UARTMsgTx1[i+1] = output_buffer2[j];
       	        	j = j + 1;
       	        }

       	        j = 0;
       	        for (i = 0; i < 512; i =  i + 2)
       	        {
       	        	UARTMsgTx3[i]   = output_buffer3[j]>>8;
       	        	UARTMsgTx3[i+1] = output_buffer3[j];
       	        	j = j + 1;
       	        }


          		        	MSS_UART_polled_tx(&g_mss_uart1,(uint8_t *)&UARTMsgTx1,2048);
          		        	delay(100);
          		        	MSS_UART_polled_tx(&g_mss_uart1,(uint8_t *)&UARTMsgTx2,512);
          		        	delay(100);
          		        	MSS_UART_polled_tx(&g_mss_uart1,(uint8_t *)&UARTMsgTx3,512);
          		        	delay(100);


          		         		memset(UARTMsgTx1,0,sizeof (UARTMsgTx1));
          		         		memset(UARTMsgTx2,0,sizeof (UARTMsgTx2));
          		         		memset(UARTMsgTx3,0,sizeof (UARTMsgTx3));
          		         		memset(input_buffer,0,sizeof (input_buffer));
          		         		memset(output_buffer,0,sizeof (output_buffer));
          		         		memset(output_buffer2,0,sizeof (output_buffer2));
          		         		memset(output_buffer3,0,sizeof (output_buffer3));

       		return;
}
