#include "HCB_System_Process.h"
#include "port.h"
#include "hardware.h"
#include "environment.h"
#include "system_setup.h"
#include "tablet_control.h"
#include "machineControl.h"
#include "servo_motor.h"
#include "tablet_counter.h"
#include "step_motor.h"
#include "manual_encoder.h"
#include "timer.h"
#include "csl_intcAux.h"

#define PORT_SENSOR_UNSTAB_MASK	0x0100
#define PORT_SENSOR_MASK		0x0200
unsigned int count = 0;



#define TABLET_CAPTURE_MODE_NONE	0
#define TABLET_CAPTURE_MODE_READY	1

void SendCaptureInt(int DiskNum);
void SysProcInit(void)
{
	SetGPIOVal(GPIO_SPB_INT);
}

#pragma DATA_ALIGN(MachineStatus, 8)
TMachineStatus MachineStatus;

#pragma DATA_ALIGN(IdleProcessData, 8)
TIdleProcessData IdleProcessData;

volatile int tick = 0;

unsigned int Current50usTime;
unsigned int Current50usCounter;
#define MAX_50US_COUNT				10000000u

volatile int System_Reset_SW = 0;
unsigned int System_Reset_Trigger_Time;

void System_Idle_Process_Init(void);

//----------------------------------------------------------
void System_Process_Init(void)
{
	System_Reset_SW = FALSE;
	System_Idle_Process_Init();
}
//----------------------------------------------------------

void SendCaptureInt(int DiskNum)
{
	CSL_IntcGlobalEnableState 	state;
	int i=0,j=0;
	CSL_intcGlobalDisable(&state);	
	

	if (DiskNum == 0)
	{
		CAPTURE_INT_TRIG = 0x0001;
		for (i = 0; i < 2000; i++)
		{
			j++;
		}
		CAPTURE_INT_TRIG= 0x0000;
	}
	else
	{
		CAPTURE_INT_TRIG = 0x0002;
		for (i = 0; i < 2000; i++)
		{
			j++;
		}
		CAPTURE_INT_TRIG= 0x0000;
	}
	CSL_intcGlobalEnable(&state);	
}
//----------------------------------------------------------
void MakeMachineStatus(void)
{
	int stepMotorIndex, servoMotorIndex;
	int checkServoMotorCount = SERVO_MOTOR_COUNT;	
	
	Port_CheckStatus(&PortStatus);

	if(MachineSetupData.MachineType == MACHINE_TYPE_SELMA_ADVANCED || MachineSetupData.MachineType == MACHINE_TYPE_LIMA_ADVANCED)
	{
		checkServoMotorCount = SERVO_MOTOR_COUNT;
	}
	else
	{
		checkServoMotorCount = SERVO_MOTOR_COUNT - 1;
	}

	for (servoMotorIndex = 0; servoMotorIndex < checkServoMotorCount; servoMotorIndex++)
	{
		MachineStatus.ServoMotorEncoderDiff[servoMotorIndex] = ServoMotorInfo[servoMotorIndex].MidTermMotorRPM;
	}

	for (stepMotorIndex = 0; stepMotorIndex < MAX_STEP_MOTOR_COUNT; stepMotorIndex++)
	{
		MachineStatus.OriginDetected[stepMotorIndex] = StepMotorData[stepMotorIndex].HomeDetected;
		MachineStatus.StepMotorAbsEncoder[stepMotorIndex] = StepMotorData[stepMotorIndex].AbsEncoderVal;

		if (StepMotorData[stepMotorIndex].State == STEP_MOTOR_STATE_MOVING || StepMotorData[stepMotorIndex].State == STEP_MOTOR_STATE_BREAKING)
		{
			MachineStatus.StepMotorMoving[stepMotorIndex] = 1;
		}
		else
		{
			MachineStatus.StepMotorMoving[stepMotorIndex] = 0;
		}
	}

	MachineStatus.MEStatus.MotorIndex = ManualEncoderInfo.ControlMotorIndex;
	MachineStatus.MEStatus.FeedRate = ManualEncoderInfo.FeedRate;

	MachineStatus.BFEmptySensorRatio = BowlFeederSensorInfo.Sensor1OnRatio;
	MachineStatus.BFFullSensorRatio = BowlFeederSensorInfo.Sensor2OnRatio;
	MachineStatus.VFSpeed = VibratorControlData.CurrentSpeed;
	 
	if (PORT_ReadInPort(IP_ME_EMERGENCY_OFF))
	{
		MachineStatus.MEStatus.Connected = 1;
	}
	else
	{
		MachineStatus.MEStatus.Connected = 0;
	}
	if (PORT_ReadInPort(IP_ME_ENABLE))
	{
		MachineStatus.MEStatus.Enabled = 1;
	}
	else
	{
		MachineStatus.MEStatus.Enabled = 0;
	}
}
//----------------------------------------------------------
void MakeStatusList(void)
{
	MachineStatus.ControlMode = MachineControlMode;
	
	if (MachineWarningState.WarningExist)
	{
		MachineStatus.WarningExist = 1;
	}
	else
	{
		MachineStatus.WarningExist = 0;
	}
	if (MachineAlarmState.AlarmExist)
	{
		MachineStatus.AlarmExist = 1;
	}
	else
	{
		MachineStatus.AlarmExist = 0;
	}

	switch(MainControlData.State)
	{
		case MAIN_CONTROL_STATE_STOP:
			MachineStatus.OperationState = MACHINE_STATE_STOP;
			break;
		case MAIN_CONTROL_STATE_RUN:
			MachineStatus.OperationState = MACHINE_STATE_RUN;
			break;
		case MAIN_CONTROL_STATE_CLEANING:
			MachineStatus.OperationState = MACHINE_STATE_CLEANING;
			break;
		case MAIN_CONTROL_STATE_ATTACHING:
			MachineStatus.OperationState = MACHINE_STATE_ATTACHING;
			break;
		case MAIN_CONTROL_STATE_DETACHING:
			MachineStatus.OperationState = MACHINE_STATE_DETACHING;
			break;
		case MAIN_CONTROL_STATE_STARTING:
			MachineStatus.OperationState = MACHINE_STATE_STARTING;
			break;
		case MAIN_CONTROL_STATE_STOPPING:
			MachineStatus.OperationState = MACHINE_STATE_STOPPING;
			break;
		case MAIN_CONTROL_STATE_EMERGENCY_STOP:
			MachineStatus.OperationState = MACHINE_STATE_EMERGENCY_STOP;
			break;
	}

	if (PORT_ReadInPort(IP_DISK_1_CAPTURE_LAMP1_CONNECTED) && PORT_ReadInPort(IP_DISK_1_CAPTURE_LAMP2_CONNECTED)) 
	{
		// 2015-10-28 revision by moon
		// PORT 신호가 양쪽에서 1인 경우 Capsule 조명으로 정의하였음
		MachineStatus.SuctionDisk1LampKind = MACHINE_LAMP_KIND_NORMAL_CAPSULE;
	}
	else if (PORT_ReadInPort(IP_DISK_1_CAPTURE_LAMP1_CONNECTED))
	{
		MachineStatus.SuctionDisk1LampKind = MACHINE_LAMP_KIND_NORMAL_TABLET;
	}
	else if (PORT_ReadInPort(IP_DISK_1_CAPTURE_LAMP2_CONNECTED))
	{
		MachineStatus.SuctionDisk1LampKind = MACHINE_LAMP_KIND_SUGAR_COATED_TABLET;
	}
	else
	{
		MachineStatus.SuctionDisk1LampKind = MACHINE_LAMP_KIND_DISCONNECTED;
	}

	if (PORT_ReadInPort(IP_DISK_2_CAPTURE_LAMP1_CONNECTED) && PORT_ReadInPort(IP_DISK_2_CAPTURE_LAMP2_CONNECTED)) 
	{
		MachineStatus.SuctionDisk2LampKind = MACHINE_LAMP_KIND_NORMAL_CAPSULE;
	}
		else if (PORT_ReadInPort(IP_DISK_2_CAPTURE_LAMP1_CONNECTED))
	{
		MachineStatus.SuctionDisk2LampKind = MACHINE_LAMP_KIND_NORMAL_TABLET;
	}
	else if (PORT_ReadInPort(IP_DISK_2_CAPTURE_LAMP2_CONNECTED))
	{
		MachineStatus.SuctionDisk2LampKind = MACHINE_LAMP_KIND_SUGAR_COATED_TABLET;
	}
	else
	{
		MachineStatus.SuctionDisk2LampKind = MACHINE_LAMP_KIND_DISCONNECTED;
	}
}
//----------------------------------------------------------
void System_Idle_Process_Init(void)
{
	int listIndex;
	IdleProcessData.CurrentIndex = 0;
	IdleProcessData.CurrentTime = 0;
	for (listIndex = 0; listIndex < IDLE_PROCESS_LIST_COUNT; listIndex++)
	{
		IdleProcessData.Time[listIndex] = 0;
		IdleProcessData.TimeCounter[listIndex] = 0;
		IdleProcessData.Min50usCount[listIndex] = 0;
		IdleProcessData.Max50usCount[listIndex] = MAX_50US_COUNT;
	}      
	Current50usCounter = 0;
	Current50usTime = board50usTmr;
}
//----------------------------------------------------------
void System_Idle_Process(void)
{	
	if (Current50usTime == board50usTmr)
	{
		Current50usCounter++;
	}
	else
	{
		if (board50usTmr - Current50usTime - 1 != 0)
		{
			IdleProcessData.Min50usCount[IdleProcessData.CurrentIndex] = 0;	
		}
		else
		{
			if (IdleProcessData.Min50usCount[IdleProcessData.CurrentIndex] > Current50usCounter)
			{
				IdleProcessData.Min50usCount[IdleProcessData.CurrentIndex] = Current50usCounter;
			}
		}
		if (IdleProcessData.Max50usCount[IdleProcessData.CurrentIndex] < Current50usCounter)
		{
			IdleProcessData.Max50usCount[IdleProcessData.CurrentIndex] = Current50usCounter;
		}
		Current50usCounter = 0;
		Current50usTime = board50usTmr;
	}

	if (IdleProcessData.CurrentTime == Board100MSTmr)
	{
		IdleProcessData.TimeCounter[IdleProcessData.CurrentIndex]++;
	}
	else
	{
		IdleProcessData.CurrentIndex = (IdleProcessData.CurrentIndex + 1) & IDLE_PROCESS_LIST_MASK;
		IdleProcessData.CurrentTime = Board100MSTmr;
		IdleProcessData.Time[IdleProcessData.CurrentIndex] = Board100MSTmr;
		IdleProcessData.TimeCounter[IdleProcessData.CurrentIndex] = 1;
		IdleProcessData.Min50usCount[IdleProcessData.CurrentIndex] = MAX_50US_COUNT;
		IdleProcessData.Max50usCount[IdleProcessData.CurrentIndex] = 0;
	}
}
//----------------------------------------------------------
void HCB_System_Process_20ms(void)
{
	CSL_IntcGlobalEnableState 	state;
	if (System_Reset_SW)
	{
		if ((int)(Board1MSTmr - System_Reset_Trigger_Time) > 100)
		{
			System_Reset_SW = FALSE;

			CSL_intcGlobalDisable(&state);
			jump();
		}		
	}
}
//----------------------------------------------------------
