/****************************************************************************\
 *           Copyright (C) 2012 Texas Instruments Incorporated.             *
 *                           All Rights Reserved                            *
 *                                                                          *
 * GENERAL DISCLAIMER                                                       *
 * ------------------                                                       *
 * All software and related documentation is provided "AS IS" and without   *
 * warranty or support of any kind and Texas Instruments expressly disclaims*
 * all other warranties, express or implied, including, but not limited to, *
 * the implied warranties of merchantability and fitness for a particular   *
 * purpose.  Under no circumstances shall Texas Instruments be liable for   *
 * any incidental, special or consequential damages that result from the    *
 * use or inability to use the software or related documentation, even if   *
 * Texas Instruments has been advised of the liability.                     *
 ****************************************************************************
This example shows SPI master mode operations:
1. SPI loopback
2. read/write SPI EEPROM
 ****************************************************************************
 * Created by :                                                             *
 *            Brighton Feng                                                 *
 *            Texas Instruments                                             * 
 *            Feb 25, 2012                                                  *
 *                                                                          *
 *            Dec 3,  2013 Cheng Peng Updated                               *
***************************************************************************/
#include <c6x.h>
#include <stdio.h>
#include "KeyStone_common.h"
#include "KeyStone_SPI_init_drv.h"
#include "SPI_loopback_TEST.h"
#include "SPI_EEPROM_test.h"
#include "SPI_Intc.h"
#include "SPI_EDMA_Test.h"


#define SPI_LOOPBACK_TEST 		1
#define SPI_EEPROM_TEST 		1
#define SPI_EDMA_TEST           1

SPI_Config spiCfg;
SPI_Interrupt_Config spiIntCfg;


void SPI_Init()
{
	/*data format for EEPROM test*/
	spiCfg.dataFormat[0]= &EepromDataFormat;

	/*data format for loopback test*/
	spiCfg.dataFormat[1]= &loopbackDataFormat;

	/*data format for EDMA loopback test*/	
	spiCfg.dataFormat[2]= &EdmaDataFormat;

	spiIntCfg.overrunInterruptEnable= TRUE;
	spiIntCfg.bitErrorInterruptEnable= TRUE;
	spiCfg.interruptCfg     = &spiIntCfg;	  
	
	
	spiCfg.number_SPI_pins  = 4;
	spiCfg.CS_polarity      =SPI_CS_LOW_ACTIVE;

	KeyStone_SPI_init(&spiCfg);
}


void main()
{
	Uint32 tscl, tsch;
	int iEEPROM_size_KB;
	int iEEPROM_addres_width;	
	TDSP_Board_Type DSP_Board_Type;

    CACHE_setL1PSize(CACHE_L1_32KCACHE);
    CACHE_setL1DSize(CACHE_L1_32KCACHE);
    CACHE_setL2Size(CACHE_0KCACHE);

	TSC_init();
    IER= 0;


	/*clear configuration structure to default values*/
	memset(&spiCfg, 0, sizeof(spiCfg));
	memset(&spiIntCfg, 0, sizeof(spiIntCfg));
	
	DSP_Board_Type= KeyStone_Get_dsp_board_type();
	
	if(C6678_EVM==DSP_Board_Type)
	{
		//DSP core speed: 100*10/1=1000MHz
		KeyStone_main_PLL_init(100, 10, 1); 

		//On Shannon, SPI belong to clock domain 3 which need be enabled
		KeyStone_enable_PSC_module(CSL_PSC_PD_ALWAYSON, 3);
#if SPI_EEPROM_TEST
		/*N25Q128 EEPROM test on Shannon EVM*/
		EepromDataFormat.clockSpeedKHz =54000;
		iEEPROM_size_KB= 16*1024;
		uiSPI_EEPROM_page_size= 256;
		needEraseBeforeWrite= TRUE;
#endif
	}
	else if(C6670_EVM==DSP_Board_Type)
	{
		//DSP core speed: 122.88*236/29= 999.9889655MHz
		KeyStone_main_PLL_init(122.88, 236, 29);

#if SPI_EEPROM_TEST
		/*N25Q128 EEPROM test on Nyquist EVM*/
		EepromDataFormat.clockSpeedKHz =54000;
		iEEPROM_size_KB= 16*1024;
		uiSPI_EEPROM_page_size= 256;
		needEraseBeforeWrite= TRUE;
#endif
	}
	else if(TCI6614_EVM==DSP_Board_Type)
	{
		//DSP core speed: 122.88*236/29= 999.9889655MHz
		KeyStone_main_PLL_init(122.88, 236, 29);

#if SPI_EEPROM_TEST
		/*N25Q032 EEPROM test on Appleton EVM*/
		EepromDataFormat.clockSpeedKHz =54000;
		iEEPROM_size_KB= 4*1024;
		uiSPI_EEPROM_page_size= 256;
		needEraseBeforeWrite= TRUE;
#endif
	}
	else if(DUAL_NYQUIST_EVM==DSP_Board_Type)
	{
		//DSP core speed: 122.88*236/29= 999.9889655MHz
		KeyStone_main_PLL_init(122.88, 236, 29);

#if SPI_EEPROM_TEST
		/*AT25640B EEPROM test on dual Nyquist EVM*/
		EepromDataFormat.clockSpeedKHz =5000;
		iEEPROM_size_KB= 8;
		uiSPI_EEPROM_page_size= 32;
		needEraseBeforeWrite= FALSE;
#endif
	}
	else if(C6657_EVM==DSP_Board_Type)
	{
		//DSP core speed: 100*10/1=1000MHz
		KeyStone_main_PLL_init(100, 10, 1);

#if SPI_EEPROM_TEST
		/*N25Q032 EEPROM test on Appleton EVM*/
		EepromDataFormat.clockSpeedKHz =54000;
		iEEPROM_size_KB= 2*1024;
		uiSPI_EEPROM_page_size= 256;
		needEraseBeforeWrite= TRUE;
#endif
	}
	else
	{
		puts("Unknown DSP board type!");
		return;
	}

    SPI_Interrupts_Init();

    
#if SPI_LOOPBACK_TEST	
	spiCfg.loopBack = TRUE;	
    spiCfg.DMA_requestEnable= FALSE;
    
	SPI_Init();	
	printf("\nSPI internal loopback test at %dMHz...\n",
		loopbackDataFormat.clockSpeedKHz/1000);
	SPI_loopback_test();
#endif
	
#if SPI_EDMA_TEST     
    SPI_EDMA_Init(); 
    
    spiCfg.loopBack = TRUE;
    spiCfg.DMA_requestEnable= TRUE;
	SPI_Init();
	printf("\nSPI EDMA test at %dMHz...\n",EdmaDataFormat.clockSpeedKHz/1000);
	    
	SPI_EDMA_test();	
#endif


#if SPI_EEPROM_TEST
	spiCfg.loopBack = FALSE;	
    spiCfg.DMA_requestEnable= FALSE;
	SPI_Init();

	if(iEEPROM_size_KB>(16*1024))
		iEEPROM_addres_width = 32;
	else if(iEEPROM_size_KB>(64))
		iEEPROM_addres_width = 24;
	else
		iEEPROM_addres_width = 16;

	printf("\nSPI EEPROM test at %dMHz...\n",
		EepromDataFormat.clockSpeedKHz/1000);

	if(iEEPROM_addres_width>24) 	//enabele 4 bytes address
		SPI_EEPROM_command(SPI_EEPROM_EN4B);

	Uint8 ID[4];
	SPI_EEPROM_ID_read(ID);
	printf("Read SPI EEPROM ID = 0x%x 0x%x 0x%x\n", ID[0], ID[1], ID[2]);
	
	if(iEEPROM_size_KB<=256)
		SPI_EEPROM_Test(0, iEEPROM_size_KB*1024, iEEPROM_addres_width);
	else
	{
		int i;
		/*spilt large space into small sections to show the progress,
		reserved the first half, only test the second half to save time*/
		//for(i=iEEPROM_size_KB/2; i<iEEPROM_size_KB; i+= 256)
		for(i=iEEPROM_size_KB*7/8; i<iEEPROM_size_KB; i+= 256)
			SPI_EEPROM_Test(i*1024, (i+256)*1024, iEEPROM_addres_width);
	}
#endif
	
	tscl= TSCL;
	tsch= TSCH;
	printf("SPI test complete at %lld cycle\n", _itoll(tsch, tscl));
	CACHE_invAllL1p(CACHE_WAIT);
	CACHE_wbInvAllL1d(CACHE_WAIT);
	CSL_XMC_invalidatePrefetchBuffer();
	_mfence();
	_mfence();
}


