#include "hardware.h"
#include "port.h"
#include "machineControl.h"
#include <csl_tmr.h>
#include <csl_tmrAux.h>
#include <csl_intc.h>
#include <csl_intcAux.h>
#include <soc.h>

CSL_GpioHandle hGpio;
CSL_GpioObj             	gpioObj;

CSL_IntcObj                 intcTimerObj;
CSL_IntcHandle              hIntcTimer;
int valGpio;

static int lamp1, lamp2;
unsigned int bitSignal = 0x0008;
THCBFPGAVersion HCbFPGAVerInfo;

int GPIO_USB = CSL_GPIO_PIN5;
int GPIO_DISK1_THREED_SENSOR = CSL_GPIO_PIN10;
int GPIO_DISK2_THREED_SENSOR = CSL_GPIO_PIN12;
int GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN15;//CSL_GPIO_PIN9
int GPIO_SPB_INT = CSL_GPIO_PIN11;//CSL_GPIO_PIN11

int GPIO_EN = 0;
int GPIO_DIR= 0;

TInverterParmInfo InverterParmInfo[2];

void HARDWARE_LampInit(void)
{
	lamp1 = 0;
	LAMP1 = 0;
	lamp2 = 0;
	LAMP2 = 0;
}

void HARDWARE_Lamp1Off(void)
{
	lamp1 = 0;
	LAMP1 = 0;
}

void HARDWARE_Lamp1On(void)
{
	lamp1 = 1;
	LAMP1 = 1;
}

void HARDWARE_Lamp1Toggle(void)
{
  	if (lamp1) 
	{
		lamp1 = 0;
		LAMP1 = 0;
	} 
	else 
	{
		lamp1 = 1;
		LAMP1 = 1;
	}
}

void HARDWARE_Lamp2Off(void)
{
	lamp2 = 0;
	LAMP2 = 0;
}

void SetInverterSpeed(int inverterIndex , int speed)
{
	InverterParmInfo[inverterIndex].Speed = speed;
	InverterParmInfo[inverterIndex].WriteRetryCount = 0;
	InverterParmInfo[inverterIndex].WriteFlag = 1;
}

void HARDWARE_LampShift(void)
{
	if(bitSignal > 0x0100)
		bitSignal = 0x0008;

	*ADD_02_UNKNOWN_NAME = bitSignal;
	bitSignal = bitSignal << 1;
}

void HARDWARE_Lamp2On(void)
{
	lamp2 = 1;
	LAMP2 = 1;
}

void HARDWARE_Lamp2Toggle(void)
{
	if (lamp2) 
	{
		lamp2 = 0;
		LAMP2 = 0;
	} 
	else 
	{
		lamp2 = 1;
		LAMP2 = 1;
	}
}

void HARDWARE_InitGPIO(int type)

{
	CSL_GpioPinConfig config;
	CSL_GpioContext pContext;
	CSL_GpioHwSetup hwSetup;
	CSL_Status status;

	status = CSL_gpioInit(&pContext);
	if (status != CSL_SOK)
	{
		return ;
	}
	
/* FPGA 버전 정보 활용하기 어려워서 막아놓음.
	HCbFPGAVerInfo.Program = FPGA_PROGRAM_RIVISION_VER & 0x00FF;
	HCbFPGAVerInfo.Rivision = (FPGA_PROGRAM_RIVISION_VER & 0xFF00) >> 8;
	HCbFPGAVerInfo.Borad = FPGA_BOARD_CHECKSUM_VER & 0x00FF;
	HCbFPGAVerInfo.Checksum = (FPGA_BOARD_CHECKSUM_VER & 0xFF00) >> 8;
	if (HCbFPGAVerInfo.Checksum == (HCbFPGAVerInfo.Program + HCbFPGAVerInfo.Rivision + HCbFPGAVerInfo.Borad)&0xFF)
	{
		if (HCbFPGAVerInfo.Borad == 0x05)
		{
			if (HCbFPGAVerInfo.Program >= 0x20 || HCbFPGAVerInfo.Rivision >= 0x13)
			{
				GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN9;
				GPIO_SPB_INT = CSL_GPIO_PIN11;

				GPIO_EN = (GPIO_USB | GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
				GPIO_DIR = (GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
			}
			else
			{
				if (LasercomplexerInfo.Laser_complexer_Enable == 1)
				{
					GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN9;

					GPIO_SPB_INT = CSL_GPIO_PIN11;
				}
				else
				{
					GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN15;
					GPIO_SPB_INT = CSL_GPIO_PIN11;
				}

				GPIO_EN = (GPIO_USB | GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
				GPIO_DIR = (GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
			}
		}
		else if (HCbFPGAVerInfo.Borad == 0x06)
		{
			GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN9;
			GPIO_SPB_INT = CSL_GPIO_PIN11;

			GPIO_EN = (GPIO_USB | GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
			GPIO_DIR = (GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
		}
		else
		{
			if (LasercomplexerInfo.Laser_complexer_Enable == 1)
			{
				GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN9;

				GPIO_SPB_INT = CSL_GPIO_PIN11;
			}
			else
			{
				GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN15;
				GPIO_SPB_INT = CSL_GPIO_PIN11;
			}
			GPIO_EN = (GPIO_USB | GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
			GPIO_DIR = (GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
		}
	}
	else
	{
		if (LasercomplexerInfo.Laser_complexer_Enable == 1)
		{
			GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN9;
			GPIO_SPB_INT = CSL_GPIO_PIN11;
		}
		else
		{
			GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN15;
			GPIO_SPB_INT = CSL_GPIO_PIN11;
		}
		GPIO_EN = (GPIO_USB | GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
		GPIO_DIR = (GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
	}
*/

	if (type == MACHINE_TYPE_LIMA_BASIC ||type == MACHINE_TYPE_LIMA_ADVANCED || type == MACHINE_TYPE_SELMA_ADVANCED)
	{
		GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN9;
		GPIO_SPB_INT = CSL_GPIO_PIN11;
	}
	else
	{
		GPIO_MCBSP_2_RS485 = CSL_GPIO_PIN15;
		GPIO_SPB_INT = CSL_GPIO_PIN13;
	}
	GPIO_EN = (GPIO_USB | GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
	GPIO_DIR = (GPIO_SPB_INT | GPIO_MCBSP_2_RS485);
	
	/* Open the CSL module */
	hGpio = CSL_gpioOpen(&gpioObj, CSL_GPIO, NULL, &status);
	if ((hGpio == NULL) || (status != CSL_SOK))
	{
		return ;
	}

	config.pinNum = GPIO_SPB_INT;
	config.trigger = CSL_GPIO_TRIG_CLEAR_EDGE;
	config.direction = CSL_GPIO_DIR_OUTPUT;
	status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_CONFIG_BIT, &config);
	if (status != CSL_SOK)
	{
		return ;
	}

	config.pinNum = GPIO_MCBSP_2_RS485;
	config.trigger = CSL_GPIO_TRIG_RISING_EDGE;
	config.direction = CSL_GPIO_DIR_OUTPUT;
	status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_CONFIG_BIT, &config);
	if (status != CSL_SOK)
	{
		return ;
	}

	config.pinNum = GPIO_DISK1_THREED_SENSOR;
	config.trigger = CSL_GPIO_TRIG_FALLING_EDGE;
	config.direction = CSL_GPIO_DIR_INPUT;
	status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_CONFIG_BIT, &config);
	if (status != CSL_SOK)
	{
		return ;
	}

	config.pinNum = GPIO_DISK2_THREED_SENSOR;
	config.trigger = CSL_GPIO_TRIG_FALLING_EDGE;
	config.direction = CSL_GPIO_DIR_INPUT;
	status = CSL_gpioHwControl(hGpio, CSL_GPIO_CMD_CONFIG_BIT, &config);

	if (status != CSL_SOK)
	{
		return ;
	}
}



void SetGPIOVal(CSL_GpioPinNum pinNum)
{
	hGpio->regs->SET_DATA |= (0x1 << pinNum);
}
void ResetGPIOVal(CSL_GpioPinNum pinNum)
{
	hGpio->regs->CLR_DATA |= (0x1 << pinNum);	
}

void HARDWARE_InitializeTimer0(void)
{
	CSL_TmrHandle TimerHandle1;
	CSL_TmrObj TmrObj;
	CSL_Status status;
	CSL_TmrHwSetup hwSetup = CSL_TMR_HWSETUP_DEFAULTS;
	CSL_TmrEnamode TimeCountMode = CSL_TMR_ENAMODE_CONT;
	Uint32 LoadValue = 0x1CB6 ;	// 0.05ms  =  ((50us * 850MHz / 6) / 12)

	// Event Enable
	CSL_tmrInit(NULL);
	TimerHandle1 = CSL_tmrOpen (&TmrObj, CSL_TMR_1, NULL, &status);

	status = CSL_tmrHwSetup(TimerHandle1, &hwSetup);
	hwSetup.tmrClockPulseLo = CSL_TMR_CP_CLOCK;
	hwSetup.tmrTimerMode = CSL_TMR_TIMMODE_DUAL_UNCHAINED;
	hwSetup.tmrClksrcLo = CSL_TMR_CLKSRC_INTERNAL;
	status = CSL_tmrHwSetup(TimerHandle1, &hwSetup);
	status = CSL_tmrHwControl(TimerHandle1, CSL_TMR_CMD_RESET_TIMLO, NULL);
	status = CSL_tmrHwControl(TimerHandle1, CSL_TMR_CMD_LOAD_PRDLO, (void *)&LoadValue);

	status = CSL_tmrHwControl(TimerHandle1, CSL_TMR_CMD_START_TIMLO, (void *)&TimeCountMode);
	CSL_intcInterruptEnable(CSL_INTC_VECTID_5);	
}

int HARDWARE_ReadDIP()
{
	return (~DIPSW >> 4) & 0xF;
}



