#include <csl.h>
#include <csl_emifa.h>
#include <soc.h>
#include <cslr_dev.h>
#include <csl_psc.h>
#include <csl_ddr2.h>
#include <csl_pllc.h>
#include <csl_emifa.h>
#include <csl_emifaAux.h>
#include <csl_intc.h>
#include <csl_intcAux.h>
#include "hardware.h"
#include "environment.h"
#include "HCB_System_Process.h"
#include "system_setup.h"
#include "timer.h"
#include "machineControl.h"
#include "capture.h"
#include <csl_intc.h>
#include <csl_intcAux.h>
#include "port.h"
extern far void vectors();
extern unsigned char Servo_PacketTest;
int MainLoopwait();
void MachineStatusInit();
int InitModule();
void InitDev();
void InitEMIFA();
void InitDDR2();
void InitPllc_850M();
void SetPscModule(CSL_PscPowerDomain pwrDmn, CSL_PscPeripherals module);
int led_count;
// default emif values

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


volatile unsigned int CheckSW;
unsigned int processPriorityCounter = 0;
unsigned int processRS485PriorityCounter = 0;
int machineStatusReadInterval=0;

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

    /* 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=CSL_EMIFA_ASYNCCFG_DEFAULTS,ce3Config = CSL_EMIFA_ASYNCCFG_DEFAULTS,ce4Config ,ce5Config = CSL_EMIFA_ASYNCCFG_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 = 1;
	ce2Config.wStrobe = 3;
	ce2Config.wHold = 1; 
	ce2Config.rSetup = 1;    
	ce2Config.rStrobe = 5;  
	ce2Config.rHold = 1;      
	ce2Config.asize = 1;

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

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

	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_ASYNC;
	ce4Val.async = &ce4Config;
	ce4Val.sync = NULL;

	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;   	
	hwSetup.ceCfg[1] = &ce3Val;		
	hwSetup.ceCfg[2] = &ce4Val;		
	hwSetup.ceCfg[3] = &ce5Val; 	

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

	CSL_intcInit(&IntcContext);
}


void MachineStatusInit()
{
	Servo_Motor_Run(SD1_MOTOR_INDEX, MainControlData.MotorSpeed[SD1_MOTOR_INDEX]);
	Servo_Motor_Run(SD2_MOTOR_INDEX, MainControlData.MotorSpeed[SD2_MOTOR_INDEX]);
	Servo_Motor_Run(BF_ID_MOTOR_INDEX, MainControlData.MotorSpeed[BF_ID_MOTOR_INDEX]);
	Servo_Motor_Run(BF_OD_IN_MOTOR_INDEX, MainControlData.MotorSpeed[BF_OD_IN_MOTOR_INDEX]);
	Servo_Motor_Run(BF_OD_OUT_MOTOR_INDEX, MainControlData.MotorSpeed[BF_OD_OUT_MOTOR_INDEX]);
	MC_BowlFeeder_EmergencyReset();
	MC_SuctionDisk_EmergencyReset();
	MC_Vibrator_EmergencyReset();
	MC_MainControl_EmergencyReset();
	MC_StepMotor_EmergencyReset();
	MC_NC_Control_EmergencyReset();
	MC_DustBlower_Off();
	MC_DustBlowerSol_Off();
	Servo_Motor_Stop(SD1_MOTOR_INDEX);
	Servo_Motor_Stop(SD2_MOTOR_INDEX);
	Servo_Motor_Stop(BF_ID_MOTOR_INDEX);
	Servo_Motor_Stop(BF_OD_IN_MOTOR_INDEX);
	Servo_Motor_Stop(BF_OD_OUT_MOTOR_INDEX);
}
void main()
{	
}	

int InitModule()
{
//	TErrorCode rtn;

	int dip_sw;
	int size;
	unsigned int checkS1=0,checkS2=0;

	TErrorCode ec;
	CSL_IntcGlobalEnableState 	state;
	//unsigned int gie;
	CSL_intcGlobalDisable(NULL);
	CSL_intcInterruptDisable(CSL_INTC_VECTID_14);
	/* McBSP 2 select device */
	led_count = 0;
	
	SysLibInit();
	InitPsc();
	InitEMIFA();
	
	WHDOG = 0;
	THREED_CAMERA_SENSOR = 0;
	dip_sw = HARDWARE_ReadDIP();
	if (dip_sw & 0x07) dip_sw = 0;

	BoardID = BOARD_ID_HCB((dip_sw & 0x7) + 1);
	
	Environment_Init();
	InitPllc_850M();
	InitDDR2();
	FlashReadProductId();
	if (!FlashReadFileSystem()) FlashFormat();

	InitDMAScheduler();

	/* Initialize LED  */
	HARDWARE_LampInit();
	/* Setting TIMER0  */
	TPB_Initialize();
	InitTimer();
	/* Initialize GPIO */
//	InitSlave();
	/* Initialize Master */
	RS485_MasterInit();
	MasterInit();

	// Initialize port variable
	PORT_InitPort();	

//	Servo_Motor_Init();
	Step_Motor_Init();

	TabletCounter_Init();
	SysProcInit();
	HCB_Capture_Init();
	TabletControl_Init();
	System_Process_Init();

	//SystemSetup_InitDefault();
	MachineControl_Init();

#ifndef CS_PROFILE
	HCBProgramHeader.ProjectID = PROJECT_ID_ELMA_100;
	HCBProgramHeader.ProgramRev = HCB_PROGRAM_REV;
	strcpy(HCBProgramHeader.ProjectName, PROJECT_NAME_ELMA_100); 	// for sw matching


	HCBCompatibility.SPBCompatibility = HCB_SPB_COMPATIBILITY_SPB06;

	//DB_HEADER
	ec = ReadFromFlash(PID_HCB_DB_HEADER, (unsigned char *)&HCBDBHeader, sizeof(THCBDBHeader), &size);
	checkS1 = CheckSumByte((unsigned char *)&HCBDBHeader, sizeof(THCBDBHeader));
	ec = ReadFromFlash(PID_HCB_DB_HEADER, (unsigned char *)&HCBDBHeader, sizeof(THCBDBHeader), &size);
	checkS2 = CheckSumByte((unsigned char *)&HCBDBHeader, sizeof(THCBDBHeader));
	if(checkS1 != checkS2)
	{
		ErrorUnit_Put(BoardID, ERROR_TYPE_WARNING, ERROR_CODE_FLASH_READ, PID_HCB_DB_HEADER, 0, 0);
		ec = ReadFromFlash(PID_HCB_DB_HEADER, (unsigned char *)&HCBDBHeader, sizeof(THCBDBHeader), &size);
	}
	
	if (ec != ERROR_CODE_NONE || size != sizeof(THCBDBHeader))
	{
		HCBDBHeader.DataRev = 0;			// for data matching (be written by PC)		
		WriteToFlash(PID_HCB_DB_HEADER, (unsigned char *)&HCBDBHeader, sizeof(THCBDBHeader), 0);
	}

	//MS_HEADER
	ec = ReadFromFlash(PID_HCB_MS_HEADER, (unsigned char *)&HCBMachineSpecificHeader, sizeof(THCBMachineSpecificHeader), &size);
	checkS1 = CheckSumByte((unsigned char *)&HCBMachineSpecificHeader, sizeof(THCBMachineSpecificHeader));
	ec = ReadFromFlash(PID_HCB_MS_HEADER, (unsigned char *)&HCBMachineSpecificHeader, sizeof(THCBMachineSpecificHeader), &size);
	checkS2 = CheckSumByte((unsigned char *)&HCBMachineSpecificHeader, sizeof(THCBMachineSpecificHeader));
	if(checkS1 != checkS2)
	{
		ErrorUnit_Put(BoardID, ERROR_TYPE_WARNING, ERROR_CODE_FLASH_READ, PID_HCB_MS_HEADER, 0, 0);
		ec = ReadFromFlash(PID_HCB_MS_HEADER, (unsigned char *)&HCBMachineSpecificHeader, sizeof(THCBMachineSpecificHeader), &size);
	}
	
	if (ec != ERROR_CODE_NONE || size != sizeof(THCBMachineSpecificHeader))
	{
		memset(&HCBMachineSpecificHeader, 0, sizeof(THCBMachineSpecificHeader));
		WriteToFlash(PID_HCB_MS_HEADER, (unsigned char *)&HCBMachineSpecificHeader, sizeof(THCBMachineSpecificHeader), 0);
	}

	//MACHINE_INFO
	ec = ReadFromFlash(PID_MACHINE_INFO, (unsigned char *)&MachineSetupData, sizeof(TMachineSetupData), &size);
	checkS1 = CheckSumByte((unsigned char *)&MachineSetupData, sizeof(TMachineSetupData));
	ec = ReadFromFlash(PID_MACHINE_INFO, (unsigned char *)&MachineSetupData, sizeof(TMachineSetupData), &size);
	checkS2 = CheckSumByte((unsigned char *)&MachineSetupData, sizeof(TMachineSetupData));
	if(checkS1 != checkS2)
	{
		ErrorUnit_Put(BoardID, ERROR_TYPE_WARNING, ERROR_CODE_FLASH_READ, PID_MACHINE_INFO, 0, 0);
		ec = ReadFromFlash(PID_MACHINE_INFO, (unsigned char *)&MachineSetupData, sizeof(TMachineSetupData), &size);
	}

	if (ec != ERROR_CODE_NONE || size != sizeof(TMachineSetupData))
	{
		//ErrorUnit_Put(BoardID, ERROR_TYPE_CRITICAL, ERROR_CODE_ENVIRONMENT_NOT_MATCH, 1, 0, 0);
		SystemSetup_InitDefaultMachineInfo();
		WriteToFlash(PID_MACHINE_INFO, (unsigned char *)&MachineSetupData, sizeof(TMachineSetupData), 0);		
	}

	//USER MACHINE
	ec = ReadFromFlash(PID_USER_MACHINE_ENV, (unsigned char *)&UserMachineEnv, sizeof(TUserMachineEnv), &size);
	checkS1 = CheckSumByte((unsigned char *)&UserMachineEnv, sizeof(TUserMachineEnv));
	ec = ReadFromFlash(PID_USER_MACHINE_ENV, (unsigned char *)&UserMachineEnv, sizeof(TUserMachineEnv), &size);
	checkS2 = CheckSumByte((unsigned char *)&UserMachineEnv, sizeof(TUserMachineEnv));
	if(checkS1 != checkS2)
	{
		ErrorUnit_Put(BoardID, ERROR_TYPE_WARNING, ERROR_CODE_FLASH_READ, PID_USER_MACHINE_ENV, 0, 0);
		ec = ReadFromFlash(PID_USER_MACHINE_ENV, (unsigned char *)&UserMachineEnv, sizeof(TUserMachineEnv), &size);
	}
	
	if (ec != ERROR_CODE_NONE || size != sizeof(TUserMachineEnv))
	{
		//ErrorUnit_Put(BoardID, ERROR_TYPE_CRITICAL, ERROR_CODE_ENVIRONMENT_NOT_MATCH, 2, 0, 0);
		SystemSetup_InitDefaultUserMachineEnv();
		WriteToFlash(PID_USER_MACHINE_ENV, (unsigned char *)&UserMachineEnv, sizeof(TUserMachineEnv), 0);
	}

	//TERMINATION
	ec = ReadFromFlash(PID_TERMINATION_INFO, (unsigned char *)&TerminationInfo, sizeof(TTerminationInfo), &size);
	checkS1 = CheckSumByte((unsigned char *)&TerminationInfo, sizeof(TTerminationInfo));
	ec = ReadFromFlash(PID_TERMINATION_INFO, (unsigned char *)&TerminationInfo, sizeof(TTerminationInfo), &size);
	checkS2 = CheckSumByte((unsigned char *)&TerminationInfo, sizeof(TTerminationInfo));
	if(checkS1 != checkS2)
	{
		ErrorUnit_Put(BoardID, ERROR_TYPE_WARNING, ERROR_CODE_FLASH_READ, PID_TERMINATION_INFO, 0, 0);
		ec = ReadFromFlash(PID_TERMINATION_INFO, (unsigned char *)&TerminationInfo, sizeof(TTerminationInfo), &size);
	}	
	if (ec != ERROR_CODE_NONE || size != sizeof(TTerminationInfo))
	{
		TerminationInfo.DataValid = 0;
	}
#endif	
	ApplySystemSetup();
	HARDWARE_InitGPIO(MachineSetupData.MachineType);
	Manual_Encoder_Init();

	/* Interrupt enabled */
	MC_InitialMove();
	TPB_MisejectProcessInit();
	Servo_Motor_Init();	// MachineSetupData.MachineType 적용  
	MachineStatusInit();
	PORT_ModifyOutPort(OP_LASERT_ENCODER_POLA, 1);	//0: 증가,  1: 감소	
/*		
	PORT_ModifyOutPort(OP_LASERT_TRIG_CONTROL_MODE, 1);  //0:프로그램 모드, 1:하드웨어 모드
*/
	if(MachineSetupData.LasercomplexerInfo.Laser_Trig_mode)
	{
		PORT_ModifyOutPort(OP_LASERT_TRIG_CONTROL_MODE, 1);  //0:프로그램 모드, 1:하드웨어 모드
	}
	else
	{
		PORT_ModifyOutPort(OP_LASERT_TRIG_CONTROL_MODE, 0);  //0:프로그램 모드, 1:하드웨어 모드
	}
	PORT_ModifyOutPort(OP_LASERT_ENCODER_SEL, 0); //0: 정상모드,  1: 테스트 모드
	PORT_ModifyOutPort(OP_SCANHEADER_POWER, 1);
	PORT_ModifyOutPort(OP_VARIOSCAN_POWER, 1);
	PORT_ModifyOutPort(OP_SD2_LASER_PRINT_TRIG, 1);
	LASER_TRIGER_ENCODER_SET = 100;

	//ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_NONE, 123, 456,789);
	CSL_intcGlobalNmiEnable();
	CSL_intcGlobalEnable(NULL);
	CSL_intcInterruptEnable(CSL_INTC_VECTID_14);

	return 0;
}

int MainLoopwait()
{

	if (processPriorityCounter == 0)
	{	
		MakeStatusList();
		MakeMachineStatus();
		RS485_Master_Loop_Process();
		processPriorityCounter = 99;
	}
	else
	{
		processPriorityCounter--;
	}
	PIO05_PORT_ONOFF();
	System_Idle_Process();
}	

