
/*-----------------------------------------------------------------------------
 * JESD204B Stand alone Demo
 * Date     : 17-04-2015
 * Author : Advanced Applications Engineering
 */

/*-----------------------------------------------------------------------------
 * Include Header Files
 */
	#include "..\SF2_JESD204B_DEMO_sb_MSS_CM3_hw_platform\drivers\mss_uart\mss_uart.h"
	#include "..\SF2_JESD204B_DEMO_sb_MSS_CM3_hw_platform\drivers\mss_timer\mss_timer.h"
	#include "..\SF2_JESD204B_DEMO_sb_MSS_CM3_hw_platform\drivers\mss_gpio\mss_gpio.h"
	#include "..\SF2_JESD204B_DEMO_sb_MSS_CM3_hw_platform\CMSIS\system_m2sxxx.h"
	#include <stdint.h>



/*-----------------------------------------------------------------------------
 * Pre-processor Definitions
 */
	#define ENABLE_SCRAMBLE_STATE			    0
	#define WRITE_STATE							1
	#define READ_STATE							2
	#define ADC_DATA_WR_STATE 			        3
	#define ADC_DATA_RD_STATE 			        4

    #define DEVICE_ID 		 				 0x62

#define SRAM_BASE_ADDR 0x30000000

/*------------------------------------------------------------------------------
 * Local Function Prototypes
 */
	static void menu_parser(void);
	static void delay_ms(uint16_t m_sec_val);


/*------------------------------------------------------------------------------
 * Global Variable Declarations
 */
	static uint32_t g_term_state = READ_STATE;
	volatile uint8_t g_tim_bit = 0;

    uint32_t *fab_sram_word_ptr;
    uint32_t output_buffer[4096];
    uint16_t output_buffer1[4096];

    uint8_t UARTMsgTx1[8192];

	uint8_t rx_buff[40];

	uint8_t prbs;


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

/*------------------------------------------------------------------------------
 * Main Function
 */
int main()
{
	/*--------------------------------------------------------------------------
	 * Local Variable Declarations
	 */
	uint8_t rx_size = 0;
    uint8_t tx_buff[2] = {0x09,0x0E};


    /*--------------------------------------------------------------------------
     * Initialise UART 0
     */

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


	/*--------------------------------------------------------------------------
     * Configure Timer 2
     */
	SystemCoreClockUpdate();	  //Reads in the exact current clock frequency from the register.
    MSS_TIM2_init( MSS_TIMER_ONE_SHOT_MODE );

    /*
     * Initialize MSS GPIOs.
     */
    MSS_GPIO_init();

    /*
     * Configure MSS GPIOs.
     */
    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 );
    MSS_GPIO_config( MSS_GPIO_3 , MSS_GPIO_OUTPUT_MODE );
    MSS_GPIO_config( MSS_GPIO_4 , MSS_GPIO_OUTPUT_MODE );
    MSS_GPIO_config( MSS_GPIO_5 , MSS_GPIO_OUTPUT_MODE );
    MSS_GPIO_config( MSS_GPIO_6 , MSS_GPIO_OUTPUT_MODE );
	delay_ms(750);                                                                      //Power on enable signal goes high.

	while(1)
	{
		rx_size = 0;
		rx_buff[0] = 0;
		memset(rx_buff,0,sizeof (rx_buff));
//		delay_ms(1);
		rx_size = UART_Polled_Rx( &g_mss_uart1, rx_buff, 2);
//		delay_ms(1);
		  switch(rx_buff[0])
		    {
	           case 9 :
	               	MSS_UART_polled_tx( &g_mss_uart1, tx_buff, 2 );
	    	          break;

	           case 1 :
		    	          g_term_state = ADC_DATA_WR_STATE;
		    	          menu_parser();
		    	   //       delay_ms(1);

		    	          break;
		       case 2 :
	    	          g_term_state = ADC_DATA_RD_STATE;
	    	          menu_parser();
	    	          break;

		       case 3 :
			    	  MSS_GPIO_set_output(MSS_GPIO_5, 1);
	    	          break;

		       case 4 :
			    	  MSS_GPIO_set_output(MSS_GPIO_5, 0);
			    	  MSS_GPIO_set_output(MSS_GPIO_6, 0);
	    	          break;
		       case 5 :
			    	  MSS_GPIO_set_output(MSS_GPIO_6, 1);
	    	          break;
		       default : break;
		     }

		}
}

/*------------------------------------------------------------------------------
 * Menu_State_Machine
 */
void
menu_parser(void)
{


	uint32_t j=0, i=0;

	switch(g_term_state)
	{

	case ADC_DATA_WR_STATE :
        fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;

		      if(rx_buff[1] == 0)
		      {
		    	  MSS_GPIO_set_output(MSS_GPIO_2, 0);
		    	  MSS_GPIO_set_output(MSS_GPIO_3, 0);
		    	  MSS_GPIO_set_output(MSS_GPIO_4, 0);
		    	  prbs =0;
		      }
		      else if(rx_buff[1] == 1)
		      {
		    	  MSS_GPIO_set_output(MSS_GPIO_2, 0);
		    	  MSS_GPIO_set_output(MSS_GPIO_3, 0);
		    	  MSS_GPIO_set_output(MSS_GPIO_4, 1);
		    	  prbs =0;
		      }
		      else if(rx_buff[1] == 2)
		      {
		    	  MSS_GPIO_set_output(MSS_GPIO_2, 0);
		    	  MSS_GPIO_set_output(MSS_GPIO_3, 1);
		    	  MSS_GPIO_set_output(MSS_GPIO_4, 0);
		    	  prbs =0;
		      }
		      else if(rx_buff[1] == 3)
		      {
		    	  MSS_GPIO_set_output(MSS_GPIO_2, 0);
		    	  MSS_GPIO_set_output(MSS_GPIO_3, 1);
		    	  MSS_GPIO_set_output(MSS_GPIO_4, 1);
		    	  prbs =0;
		      }
		      else if(rx_buff[1] == 4)
		      {
		    	  MSS_GPIO_set_output(MSS_GPIO_2, 1);
		    	  MSS_GPIO_set_output(MSS_GPIO_3, 0);
		    	  MSS_GPIO_set_output(MSS_GPIO_4, 0);
		    	  prbs =1;
		      }
		      else if(rx_buff[1] == 5)
		      {
		    	  MSS_GPIO_set_output(MSS_GPIO_2, 1);
		    	  MSS_GPIO_set_output(MSS_GPIO_3, 0);
		    	  MSS_GPIO_set_output(MSS_GPIO_4, 1);
		    	  prbs =1;
		      }
		      else if(rx_buff[1] == 6)
		      {
		    	  MSS_GPIO_set_output(MSS_GPIO_2, 1);
		    	  MSS_GPIO_set_output(MSS_GPIO_3, 1);
		    	  MSS_GPIO_set_output(MSS_GPIO_4, 0);
		    	  prbs =1;
		      }
		      else if(rx_buff[1] == 7)
		      {
		    	  MSS_GPIO_set_output(MSS_GPIO_2, 1);
		    	  MSS_GPIO_set_output(MSS_GPIO_3, 1);
		    	  MSS_GPIO_set_output(MSS_GPIO_4, 1);
		    	  prbs =1;
		      }


			MSS_GPIO_set_output(MSS_GPIO_1, 1);

		break;

		case ADC_DATA_RD_STATE :

			MSS_GPIO_set_output(MSS_GPIO_1, 0);

            fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;

            MSS_GPIO_set_output(MSS_GPIO_0, 0);

    	  for( j = 0; j< 1024; j++)
    	  {
     			output_buffer[j] = *fab_sram_word_ptr;
     			fab_sram_word_ptr = fab_sram_word_ptr + 1;

    	  }

          fab_sram_word_ptr = (uint32_t *)SRAM_BASE_ADDR;

          MSS_GPIO_set_output(MSS_GPIO_0, 1);

       	  for( j = 1024; j< 2048; j++)
    	      	  {
    	       			output_buffer[j] = *fab_sram_word_ptr;
    	       			fab_sram_word_ptr = fab_sram_word_ptr + 1;

    	      	  }

 j = 0;

  	//  if(prbs == 0)

  		  for (i = 0; i < 4096; i =  i + 4)
	        {

	        	UARTMsgTx1[i+3]    = output_buffer[j];
  			    UARTMsgTx1[i+2]   = output_buffer[j]>>8;
	        	UARTMsgTx1[i+1]     = output_buffer[j]>>16;
	        	UARTMsgTx1[i]     = output_buffer[j]>>24;
	        	j = j + 1;
	        }
  //	  else
  //	  {
     		j= 1024;
  		  for (; i < 6144; i =  i + 2)
	        {
	        	UARTMsgTx1[i+1]     = output_buffer[j]>>8;
	        	UARTMsgTx1[i]    = output_buffer[j];
	        	j = j + 1;
	        }
  //	  }

	        	MSS_UART_polled_tx(&g_mss_uart1,(uint8_t *)&UARTMsgTx1,6144);

	         	memset(UARTMsgTx1,0,sizeof (UARTMsgTx1));

		break;

	}
}

/*------------------------------------------------------------------------------
 * Millisecond Delay Function
 */
void delay_ms(uint16_t m_sec_val)
{
	uint32_t timer2_load_value = 0;
    timer2_load_value = (g_FrequencyPCLK0/1000); //Gives a 1 second delay regardless of clock speed.
	timer2_load_value = (timer2_load_value * m_sec_val);
	MSS_TIM2_load_immediate( timer2_load_value );
	MSS_TIM2_start();
	MSS_TIM2_enable_irq();
	while(0 == g_tim_bit)
	{
		//Do nothing
	}
	g_tim_bit = 0;
}

/*------------------------------------------------------------------------------
 * Timer_2 Interrupt Handler
 */
void Timer2_IRQHandler( void )
{
	MSS_TIM2_clear_irq();
	g_tim_bit = 1;
}


