 #include "system.h"
//#include "define.h"
#include "common.h"
#include "environment.h"
#include "timer.h"
#include "hardware.h"
#include "spb6457cfg.h"
#include "DMAScheduler.h"
#include "TPBcamera.h"
#include "data_transfer.h"
#include "image_control.h"
#include "system_setup.h"


#include <soc.h>
#include <csl.h>
#include <csl_mcbsp.h>
#include <csl_emifa.h>
#include <csl_emifaAux.h>
#include <csl_intc.h>
#include <csl_intcAux.h>
#include <cslr_dev.h>
#include <csl_psc.h>
#include <csl_ddr2.h>
#include <csl_pllc.h>
#include <csl_cache.h>
#include <csl_edma3.h>
#include <stdio.h>

#define EMIFA_MEMTYPE_ASYNC    0
#define EMIFA_MEMTYPE_SYNC     1

volatile int temp1;
CSL_EmifaHandle    hEmifa;
CSL_IntcEventHandlerRecord  Record[15]; 
CSL_IntcContext     IntcContext;
CSL_Ddr2Handle    hDdr2;
CSL_PllcHandle           hPllc = NULL;

CSL_Edma3Obj                			NFAEdmaObj;
CSL_Edma3Handle 				hNFAEdma;
CSL_Edma3HwDmaChannelSetup  		NFADmaHwSetup[CSL_EDMA3_NUM_DMACH] = CSL_EDMA3_DMACHANNELSETUP_DEFAULT;
CSL_Edma3HwQdmaChannelSetup			NFAQdmahwSetup[CSL_EDMA3_NUM_QDMACH] = CSL_EDMA3_QDMACHANNELSETUP_DEFAULT;
CSL_Edma3HwSetup            		NFAHwSetup;

TErrorCode main_ec;
TBootRecord main_br;
int main_size = 0;
int lamp_count = 0;
volatile int Jump_SW;
int ff_error =0;
int test_count = 0;
int camera_on = 0;

char test_src[16][16];
char test_dst[16][16];

#pragma DATA_ALIGN(test_src, 32);
#pragma DATA_ALIGN(test_dst, 32);
void SetPscModule(CSL_PscPowerDomain pwrDmn, CSL_PscPeripherals module);
void InitPsc()
{
    SetPscModule(CSL_PSC_PWRDMN_ALWAYSON, CSL_PSC_MODULE_EMIF64);
    SetPscModule(CSL_PSC_PWRDMN_ALWAYSON, CSL_PSC_MODULE_HPI);
    SetPscModule(CSL_PSC_PWRDMN_ALWAYSON, CSL_PSC_MODULE_UTOPIA);
    SetPscModule(CSL_PSC_PWRDMN_PROXYA, CSL_PSC_MODULE_SRIO);
    SetPscModule(CSL_PSC_PWRDMN_PROXYB, CSL_PSC_MODULE_TCP2_0);
    SetPscModule(CSL_PSC_PWRDMN_PROXYC, CSL_PSC_MODULE_TCP2_1);
    SetPscModule(CSL_PSC_PWRDMN_PROXYD, CSL_PSC_MODULE_VCP2);
}

void InitPllc_850M()
{
    CSL_PllcObj              pllcObj;
    CSL_Status               status;
    CSL_PllcHwSetup          hwSetup;
    CSL_PllcHwSetup          hwSetupRead;
    CSL_PllcDivideControl    arg;
    CSL_PllcDivRatio         arg1;
    CSL_BitMask32            response;   
    CSL_BitMask32            argPllCtrl;    
    /* Initialize the PLLC CSL module */
    status = CSL_pllcInit(NULL);

    /* Clear local data structures */
    memset(&pllcObj, 0, sizeof(CSL_PllcObj));

    /* Open the PLLC CSL module */
    hPllc = CSL_pllcOpen (&pllcObj, CSL_PLLC_1, NULL, &status);

    /* Setup PLLC hardware parameters */
    hwSetup.divEnable  = (CSL_BitMask32) CSL_PLLC_DIVEN_POSTDIV | 
							CSL_PLLC_DIVEN_PLLDIV3 | CSL_PLLC_DIVEN_PLLDIV6 | 
							CSL_PLLC_DIVEN_PLLDIV7 | CSL_PLLC_DIVEN_PLLDIV8;

    hwSetup.postDiv    = (Uint32) 0x00000001;
    hwSetup.pllM       = (Uint32) 0x00000011;
	hwSetup.pllMode    = (Uint32) 0x00000001;
    hwSetup.pllDiv3    = (Uint32) 0x00000003;
    hwSetup.pllDiv6    = (Uint32) 0x0000000A;
	hwSetup.pllDiv7    = (Uint32) 0x00000008;
    hwSetup.pllDiv8    = (Uint32) 0x0000000A;

    status = CSL_pllcHwSetup (hPllc, &hwSetup);

    /* Read back */
    status = CSL_pllcGetHwSetup (hPllc, &hwSetupRead);

    /* Change divider settings for PLLDIV4 */

    /* Wait if another GO operation is currently in progress.*/
    do 
	{
        CSL_pllcGetHwStatus (hPllc, CSL_PLLC_QUERY_STATUS, &response);
    } while (response & CSL_PLLC_STATUS_GO);

 
    /* Close the module */
//    status = CSL_pllcClose (hPllc);

    return;
}

void SetPscModule(CSL_PscPowerDomain pwrDmn, CSL_PscPeripherals module)
{
    CSL_PscObj pscObj;
    CSL_PscHandle hPsc;
    CSL_Status status;
    CSL_PscPwrDmnTransState response;

    memset(&pscObj, 0, sizeof(CSL_PscObj));      

    /* Init PSC module */
    CSL_pscInit(NULL);

    /* Open PSC module to get a Handle */
    hPsc = CSL_pscOpen(&pscObj, CSL_PSC, NULL, &status);

	module = CSL_PSC_MODULE_EMIF64;
    /* Enable power domain for EMIFA */
    CSL_pscHwControl(hPsc, CSL_PSC_CMD_ENABLE_PWRDMN, &pwrDmn);

    /* Enable clock for the specified module EMIFA */
    CSL_pscHwControl(hPsc, CSL_PSC_CMD_ENABLE_MODULE, &module);
	
    /* Enable EMIFA Power domain GO transition */
    CSL_pscHwControl(hPsc, CSL_PSC_CMD_PWRDMN_TRNS, &pwrDmn);

    response.pwrDmn = CSL_PSC_PWRDMN_ALWAYSON;
    response.status = 0x0; 
    do{
        CSL_pscGetHwStatus(hPsc, CSL_PSC_QUERY_PWRDMN_TRANS_STAT, (void *)&response);
        (response.status) &= (1 << CSL_PSC_PWRDMN_ALWAYSON);
    }while((response.status) != 0x0);

	module = CSL_PSC_MODULE_SRIO;
    /* Enable power domain for EMIFA */
    CSL_pscHwControl(hPsc, CSL_PSC_CMD_ENABLE_PWRDMN, &pwrDmn);

    /* Enable clock for the specified module EMIFA */
    CSL_pscHwControl(hPsc, CSL_PSC_CMD_ENABLE_MODULE, &module);
	
    /* Enable EMIFA Power domain GO transition */
    CSL_pscHwControl(hPsc, CSL_PSC_CMD_PWRDMN_TRNS, &pwrDmn);

    response.pwrDmn = CSL_PSC_PWRDMN_ALWAYSON;
    response.status = 0x0; 
    do{
        CSL_pscGetHwStatus(hPsc, CSL_PSC_QUERY_PWRDMN_TRANS_STAT, (void *)&response);
        (response.status) &= (1 << CSL_PSC_PWRDMN_ALWAYSON);
    }while((response.status) != 0x0);

    /* Close the PSC module */
 //   CSL_pscClose(hPsc);
}


void InitDDR2()
{ 
	CSL_Ddr2Obj         ddr2Obj;
	CSL_Status          status;
	CSL_Ddr2HwSetup     hwSetup ;    
	CSL_Ddr2Timing1  tim1 = CSL_DDR2_TIMING1_DEFAULTS;
	CSL_Ddr2Timing2  tim2 = CSL_DDR2_TIMING2_DEFAULTS;
	CSL_Ddr2Settings set  = CSL_DDR2_SETTING_DEFAULTS;
	 /* Clear local data structures */   
	memset(&ddr2Obj, 0, sizeof(CSL_Ddr2Obj));      
	memset(&hwSetup, 0, sizeof(CSL_Ddr2HwSetup));
    
	tim1.trfc = 0x1F;
	tim1.trp = 0x3;
	tim1.trcd = 0x3;
	tim1.twr = 0x3;
	tim1.tras = 0x9;
	tim1.trc = 0xd;
	tim1.trrd = 0x2;
	tim1.twtr = 0x1;

	tim2.todt = 0x1;
	tim2.tsxnr = 0x22;
	tim2.tsxrd = 0x31;
	tim2.trtp = 0x1;
	tim2.tcke = 0x2;
    
	/* setup the hardware parameters */
	hwSetup.refreshRate = SDRAM_REFRESH_RATE;
	hwSetup.readLatncy = 0x5;
	hwSetup.timing1Param = &tim1;
	hwSetup.timing2Param = &tim2;
	set.narrowMode = CSL_DDR2_NORMAL_MODE;
	set.casLatncy = CSL_DDR2_CAS_LATENCY_4;
	set.ddr2En = 0x1;
	set.ddrEn = 0x1;
	set.ibank = CSL_DDR2_8_SDRAM_BANKS;
	set.pageSize = CSL_DDR2_1024WORD_10COL_ADDR;
	set.sdramEn = 0x1;
	set.ddr2Ddqs = CSL_DDR2_SINGLE_ENDED_DQS; 
	set.ddr2Term0 = 0x1;
	set.ddr2Term1 = 0x0;
	set.ddrDisDll = 0x0;
	set.sdramDrive0 = CSL_DDR2_SDRAM_NORMAL;
	hwSetup.setParam = &set;    
        
	/* Initialize DDR2 CSL module */
	status = CSL_ddr2Init(NULL);

    /* Opening the DDR2 instance */
    hDdr2 =  CSL_ddr2Open(&ddr2Obj, CSL_DDR2, NULL, &status);

    /* Setting up configuration parameter using HwSetup */
    status =  CSL_ddr2HwSetup(hDdr2, &hwSetup);             
}
void InitEMIFA(){
	CSL_EmifaObj          emifaObj;
	CSL_Status            status;
	CSL_EmifaHwSetup      hwSetup ;   

	CSL_EmifaMemType      ce2Val,ce3Val,ce4Val,ce5Val;
	CSL_EmifaAsyncWait    	asyncWait = CSL_EMIFA_ASYNCWAIT_DEFAULTS; 
	CSL_EmifaAsync			ce2Config,ce3Config = CSL_EMIFA_ASYNCCFG_DEFAULTS ,ce5Config;
	CSL_EmifaSync         	ce4Config = CSL_EMIFA_SYNCCFG_DEFAULTS;
	/* Clear local data structures */   
	memset(&emifaObj, 0, sizeof(CSL_EmifaObj));      
	memset(&hwSetup, 0, sizeof(CSL_EmifaHwSetup));
	
	/* setting for asynchronous type */

	ce2Config.selectStrobe = 0x0;
	ce2Config.weMode = 0x0;       
	ce2Config.asyncRdyEn = 0x1;
	ce2Config.wSetup = 0;
	ce2Config.wStrobe = 2;  
	ce2Config.wHold = 1; 
	ce2Config.rSetup = 1;    
	ce2Config.rStrobe = 5;
	ce2Config.rHold = 2;     
	ce2Config.asize = 2;

	ce5Config.selectStrobe = 0x0;
	ce5Config.weMode = 0x0;       
	ce5Config.asyncRdyEn = 0x0;
	ce5Config.wSetup = 2;
	ce5Config.wStrobe = 5;
	ce5Config.wHold = 2;
	ce5Config.rSetup = 1;    
	ce5Config.rStrobe = 7;  
	ce5Config.rHold = 1;      
	ce5Config.asize = 1;

	ce4Config.readEn = 1;
	ce4Config.r_ltncy = 3;
	ce4Config.w_ltncy = 1;
	ce4Config.sbsize = 3;


	ce2Val.ssel = CSL_EMIFA_MEMTYPE_ASYNC;
	ce2Val.async = &ce2Config;
	ce2Val.sync = NULL;

	ce3Val.ssel = CSL_EMIFA_MEMTYPE_ASYNC;
	ce3Val.async = &ce3Config;
	ce3Val.sync = NULL;

	ce4Val.ssel = CSL_EMIFA_MEMTYPE_SYNC;
	ce4Val.async = NULL;
	ce4Val.sync = &ce4Config;

	ce5Val.ssel = CSL_EMIFA_MEMTYPE_ASYNC;
	ce5Val.async = &ce5Config;
	ce5Val.sync = NULL;
	/* setting for synchronous type */
	asyncWait.asyncRdyPol = 0x0;

	hwSetup.asyncWait = &asyncWait;
	hwSetup.ceCfg[0] = &ce2Val;   		//Ce2	HPI				0xA0000000
	hwSetup.ceCfg[1] = &ce3Val;		//Ce3	Flash_spansion		0xB0000000
	hwSetup.ceCfg[2] = &ce4Val;		//Ce4	FIFO				0xC0000000
	hwSetup.ceCfg[3] = &ce5Val; 		//Ce5	Flash_samsung		0XD0000000

	status = CSL_emifaInit(NULL);
	hEmifa =  CSL_emifaOpen(&emifaObj, CSL_EMIFA, NULL, &status); 
	status =  CSL_emifaHwSetup(hEmifa, &hwSetup); 	
}
void InitIntc()
{
	
	IntcContext.numEvtEntries = 15;
    IntcContext.eventhandlerRecord = Record;

	CSL_intcInit(&IntcContext);
}
void initEDMA()
{
	CSL_Edma3Context            context;
	CSL_Status                  status; 
	int handlerIndex;

	CSL_edma3Init(&context);
	hNFAEdma =  CSL_edma3Open(&NFAEdmaObj,CSL_EDMA3,NULL,&status);
	/* Module setup */
	NFAHwSetup.dmaChaSetup = &NFADmaHwSetup[0];
	NFAHwSetup.qdmaChaSetup = &NFAQdmahwSetup[0];
	CSL_edma3HwSetup(hNFAEdma,&NFAHwSetup);	


	/* clear Parameter RAM of EDMA */
	EDMA_clearPram(0x00000000);
	

	CSL_intcInterruptEnable(CSL_INTC_VECTID_15);			//capture edma

	EDMAInterruptHandler.HandlerCount = 0;
	for (handlerIndex = 0; handlerIndex < MAX_EDMA_HANDLER_COUNT; handlerIndex++)
	{
		EDMAEventHandler[handlerIndex] = DefaultEDMAEventHandler;
	}		
}


int InitSystem()
{
	
	int size;
	int dip_sw;
	TErrorCode ec;
	CSL_IntcGlobalEnableState 	state;
	CSL_Edma3Context            	context;
	WHDOG = 0;
	ProgramVersion.MajorVersion = PROGRAM_MAJOR_VERSION;
	ProgramVersion.MinorVersion = PROGRAM_MINOR_VERSION;
	ProgramVersion.Date = PROGRAM_RELEASE_DATE;
	ProgramVersion.Type = PROGRAM_TARGET_SYSTEM; 
	Jump_SW = 0;
    	CSL_intcGlobalDisable(NULL);
// 1, set spb's ID
	SysLibInit();
	InitPsc();
	InitEMIFA();

	dip_sw = ReadDIP();
	BoardID = BOARD_ID_SPB(20);
	InitPllc_850M();
	InitDDR2();
	FlashReadProductId();
	initEDMA();
	ApplySystemInfo();
	InitDMAScheduler();
	 if (!FlashReadFileSystem())	  FlashFormat(); 	
//	FlashFormat();
	InitGPIO();
	InitMCBSP();
	LampInit();
	InitTimer();
	SystemSetup_InitDefault();
	TPBCameraInit();
// finally, interrupt enable	
	CSL_intcGlobalNmiEnable();
	CSL_intcGlobalEnable(&state);
	return 0;
}

int AllocEDMAInterruptHandler(TEDMAEventHandler edmaEventHandler, int index)
{

	EDMAEventHandler[index] = edmaEventHandler;
	return index;
}

void DefaultEDMAEventHandler(void)
{
	return;
}

int InitModule()
{
	CSL_IntcGlobalEnableState 	state;
	TErrorCode ec;
	int size;
	int i,j,count = 0;
	

	int page_addr =0;
	TBootRecord br;	
	CSL_intcInterruptDisable(CSL_INTC_VECTID_14);
	InitSystem(); 
	InitImageInfo();

	Srio_Master_Init();

	if(!(NFA_CAMERA_CONTROL_TRIG&0x8000)){
		NFACamera_Init();
	}

	InitTPBSystem();
	CPB_Auto_Boot();

	#ifdef FPGA220
		FPGAnewVersion2.VersionL = MMIO_VERSION_INFO_L;
		FPGAnewVersion2.VersionH = MMIO_VERSION_INFO_H;
	#endif
	
	TPBCaptureStop();
	THREED_CAMERA_SENSOR = 3;
	CSL_intcInterruptEnable(CSL_INTC_VECTID_14);
	CSL_intcInterruptEnable(CSL_INTC_VECTID_8);
	CSL_intcInterruptEnable(CSL_INTC_VECTID_9);
	
	if(SrioRunInfo.RunSW)
	{
		Cpb_Boot_Process();
	}

	TPMisejectInit();
	ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_MCBSP_TRANSMIT_TIMEOUT, 12,12,12);

	return 0;
}


int MainLoopwait()
{
	int i,j,count = 0;

	return 0;
}

void edmaIsr()
{
	register int eventIndex;
	CSL_IntcGlobalEnableState 	state;
	CSL_intcGlobalDisable(&state);
	for (eventIndex = 0; eventIndex < MAX_EDMA_HANDLER_COUNT; eventIndex++)
	{
		if ((CSL_FEXT(hNFAEdma->regs->IPR,EDMA3CC_IPR_REG) & (0x00000001 << eventIndex)))
		{
			hNFAEdma->regs->ICR ^= (0x00000001 << eventIndex);
			EDMAEventHandler[eventIndex]();

		}
	}
	CSL_intcGlobalEnable(&state);
}
