#include <csl_edma2.h>
#include <csl_intc.h>
#include <csl_intcAux.h>
#include "environment.h"
#include "timer.h"
#include "system_setup.h"
#include "image_control.h"
#include "spb_processing.h" 
#include "CISACam.h"
#include "capture_camera.h"
#include "SPB_Module_Main.h"
#include "fa_server.h"
#include "nfa_camera.h"

#define TABLET_NUMBER_GETTING_TIMEOUT			200//sjm chg For RUnTime 200 ==> 250		// 200 * 50us

#define RANGER_SHUTTER_SPEED_UNIT_MICRO			0.32f

#define PROCESSING_TIMEOUT						1800        //sjm chg For RunTime 1000 ==> 1250  ==> 1500		// 1000ms

#define CAPTURE_STABLE_DELAY					6

typedef struct
{
	int ProcessInfoListIndex;
	unsigned int CaptureStartTime;
} TCaptureQueueUnit;

typedef struct
{
	int TabletRotationTheta;
	int TabletCenterX;
	int TabletCenterY;
	unsigned int TriggerTime;
} TLaserQueueUnit;

#define CAPTURE_QUEUE_COUNT						256
#define CAPTURE_QUEUE_MASK						255

#define LASER_QUEUE_COUNT						512
#define LASER_QUEUE_MASK						511

#define DEFAULT_CAPTURE_FRAME_COUNT	128

// 아래 수치는 반드시 정제 크기보다 작아야함
// 정제크기보다 큰 경우 Laser에서 데이터를 write한 후 trigger 까지 대기하는 시간 동안 result 값이 다시 발생하는 경우에 overwrite 될 수 있음
// 또한 너무 짧은경우에는 HCB에서는 encoder 값을 기준으로 laser trigger를 발생하므로 오차에 의해 값이 정상적으로 write되지 않을 수 있음
// 초기 테스트버전으로 3ms 적용
#define LASER_STABLE_WAITING_TIME_50US	100

struct
{
	int QueueStart;
	int QueueEnd;
	TCaptureQueueUnit List[CAPTURE_QUEUE_COUNT];
} IntCaptureQueue[SYSTEM_SPB_CAMERA_COUNT];

int CaptureFrameCount = DEFAULT_CAPTURE_FRAME_COUNT;
int trgCount1 = 0;
int trgCount2 = 0;
int trgCount3 = 0;
int err1_cnt = 0;
int err2_cnt = 0;
int tempX = 0;
int tempY = 0;
int int_last_capture_time=0;
extern int init_camera_type[SYSTEM_SPB_CAMERA_MAX_COUNT];

int temp_del = 0;
unsigned int Max3DResultWaitingTime;

extern int test_cam_count[10];
CSL_IntcObj                 intcCaptureObj;
CSL_IntcHandle              hIntcCapture;
CSL_IntcEventHandlerRecord  CaptureEventRecord;
CSL_IntcParam               CaptureVectId;
TThreeDPositionInfo ThreeDPositionInfo_SPB_ever_sum;
TThreeDPositionInfo ThreeDPositionInfo_SPB_ever;
int ever_count;
int test_angl = 0;
void IsrIntCapture1(void);
void IsrIntCapture2(void);
void testIntCapture(int gpio);
void MakeLaserQueueData(int theta, int centerX, int centerY, int triggerTime);
void EnabledThreeDCameraSensor(int camIndex, int LSFValue, int calibrationMode);

struct
{
	int QueueStart;
	int QueueEnd;
	TLaserQueueUnit List[LASER_QUEUE_COUNT];
} LaserPositionQueue;

void ClearCaptureProcessingData(void)
{
	int captureListIndex;
	int camIndex;
	CSL_IntcEventEnableState ie;
	int i;
//	memset(&SPBTabletProcessInfo,0x00,sizeof(TSPBTabletProcessInfo));
	
	SPBTabletProcessInfo.NextCaptureListIndex = 0;
	SPBTabletProcessInfo.FindingBufferListIndex = 0;
	SPBTabletProcessInfo.NumberingCaptureListIndex = 0;
	SPBTabletProcessInfo.PollingCaptureListIndex = 0;
	SPBTabletProcessInfo.PollingCaptureAllEndListIndex = 0;
	SPBTabletProcessInfo.ProcessingAllTabletListIndex = 0;
	SPBTabletProcessInfo.ProcessingResultCheckingListIndex = 0;
	SPBTabletProcessInfo.ProcessingResultReportingListIndex = 0;
	SPBTabletProcessInfo.ProcessingAllPositionListIndex = 0;

	for(i = 0; i < 2; i++)
	{
		SPBTabletProcessInfo.TabletNumberRequestOn[i] = 0;
		SPBTabletProcessInfo.TabletNumberReceived[i] = 0;    
		SPBTabletProcessInfo.ReceivedTabletNumber[i] = 0;
		SPBTabletProcessInfo.ExpectedNextTabletNumber[i] = 1;
	}

	for (captureListIndex = 0; captureListIndex < SPB_TABLET_LIST_COUNT; captureListIndex++)
	{
		SPBTabletProcessInfo.TabletList[captureListIndex].State = SPB_TABLET_STATE_NONE;
		SPBTabletProcessInfo.TabletList[captureListIndex].Result = SPB_TABLET_RESULT_NONE;
		SPBTabletProcessInfo.TabletList[captureListIndex].ImageFrameIndex = -1;
		SPBTabletProcessInfo.TabletList[captureListIndex].TabletNumber = 0;
		SPBTabletProcessInfo.TabletList[captureListIndex].ResultReported = 0;
		SPBTabletProcessInfo.TabletList[captureListIndex].SuctionDiscPos = SD1;
		SPBTabletProcessInfo.TabletList[captureListIndex].LaserTrigerTime = 0;

		for (camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; camIndex++)
		{
			SPBTabletProcessInfo.TabletList[captureListIndex].CaptureStatus[camIndex] = CAPTURE_STATUS_NONE;
			SPBTabletProcessInfo.TabletList[captureListIndex].ThickErrorSW[camIndex] = 0;
		}
	}

	for (camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; camIndex++)
	{
		SPBTabletProcessInfo.ProcessingTabletListIndex[camIndex] = 0;
		SPBTabletProcessInfo.PollingCaptureEndListIndex[camIndex] = 0;
		SPBTabletProcessInfo.ProcessingResultListIndex[camIndex] = 0;
		SPBTabletProcessInfo.processingPositionListIndex[camIndex] = 0;
		IntCaptureQueue[camIndex].QueueStart = IntCaptureQueue[camIndex].QueueEnd = 0;
	}

	LaserPositionQueue.QueueStart = LaserPositionQueue.QueueEnd = 0;

	for (captureListIndex = 0; captureListIndex < SPB_TABLET_LIST_COUNT; captureListIndex++)
	{
		ProcessingTimeList[captureListIndex].TabletNumber = 0;
	}
	trgCount1 = 0;
	trgCount2 = 0;
//	IRQ_restore(IRQ_EVT_GPINT0, ie);
	
}

void Capture_Process(void)		// per 50us
{
	int spbCamIndex;
	//int allCaptured;
	unsigned int elapsedTime;//, prevCaptureStartTime;
	//int overlapTime;
	TSPBTabletUnit *tabletUnit, *captureTabletUnit,*last_tabletUnit;
	TCaptureQueueUnit *captureQueueUnit;	
	int cameraStatus, cameraError;
	int bAllCameraIdleStatus;
	int bError;

	if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_PROCESSING)
	{
		// check tablet number
		tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.NumberingCaptureListIndex]);
		last_tabletUnit = &(SPBTabletProcessInfo.TabletList[(SPBTabletProcessInfo.NumberingCaptureListIndex-1) & SPB_TABLET_LIST_MASK]);
		//sjm chg For RunTIme
		if (tabletUnit->State == SPB_TABLET_STATE_NUMBERING)
		{
			if (SPBTabletProcessInfo.ProcessingMode == TABLET_PROCESSING_MODE_INSPECTION)
			{
				if (SPBTabletProcessInfo.TabletNumberRequestOn[tabletUnit->SuctionDiscPos] && (SPBTabletProcessInfo.TabletNumberReceived[tabletUnit->SuctionDiscPos] || VirtualInspectionSW))
				{
					if (SPBTabletProcessInfo.ReceivedTabletNumber[tabletUnit->SuctionDiscPos] < SPBTabletProcessInfo.ExpectedNextTabletNumber[tabletUnit->SuctionDiscPos])
					{	// discard tablet number
						SPBTabletProcessInfo.TabletNumberReceived[tabletUnit->SuctionDiscPos] = 0;
					}
					else
					{
						tabletUnit->TabletNumber = SPBTabletProcessInfo.ReceivedTabletNumber[tabletUnit->SuctionDiscPos];
						SPBTabletProcessInfo.ExpectedNextTabletNumber[tabletUnit->SuctionDiscPos] = tabletUnit->TabletNumber + 1;
						VirtualSPBProcessedData[SPBTabletProcessInfo.NumberingCaptureListIndex].ProcessStartTime = Board1MSTmr; /// TEST
						ProcessingTimeList[SPBTabletProcessInfo.NumberingCaptureListIndex].TabletNumber = tabletUnit->TabletNumber;//SPBTabletProcessInfo.ReceivedTabletNumber[tabletUnit->SuctionDiscPos];
						if (SPBTabletProcessInfo.ExpectedNextTabletNumber[tabletUnit->SuctionDiscPos] > MAX_TABLET_NUMBER)
						{
							SPBTabletProcessInfo.ExpectedNextTabletNumber[tabletUnit->SuctionDiscPos] = 1;
						}						
						SPBTabletProcessInfo.TabletNumberReceived[tabletUnit->SuctionDiscPos] = 0;
						SPBTabletProcessInfo.TabletNumberRequestOn[tabletUnit->SuctionDiscPos] = 0;
						tabletUnit->State = SPB_TABLET_STATE_CAPTURE_READY;
						SPBTabletProcessInfo.NumberingCaptureListIndex = (SPBTabletProcessInfo.NumberingCaptureListIndex + 1) & SPB_TABLET_LIST_MASK;		
					}
				}
				else
				{
					elapsedTime = Board50usTimer - tabletUnit->CaptureIntTime;
					if (elapsedTime >= TABLET_NUMBER_GETTING_TIMEOUT)
					{
						// didn't get tablet number
						tabletUnit->TabletNumber = SPBTabletProcessInfo.ExpectedNextTabletNumber[tabletUnit->SuctionDiscPos];
						tabletUnit->Result = SPB_TABLET_RESULT_UNINS_TABLET_NUMBER_UNDEFINED;
						tabletUnit->State = SPB_TABLET_STATE_ERROR;
//							SPBTabletProcessInfo.ExpectedNextTabletNumber[tabletUnit->SuctionDiscPos] = tabletUnit->TabletNumber+1;
						SPBTabletProcessInfo.NumberingCaptureListIndex = (SPBTabletProcessInfo.NumberingCaptureListIndex + 1) & SPB_TABLET_LIST_MASK;
						SPBTabletProcessInfo.TabletNumberRequestOn[tabletUnit->SuctionDiscPos] = 0;
					}					

				}
			}
			else
			{
				tabletUnit->TabletNumber = SPBTabletProcessInfo.ExpectedNextTabletNumber[tabletUnit->SuctionDiscPos];
				ProcessingTimeList[SPBTabletProcessInfo.NumberingCaptureListIndex].TabletNumber = SPBTabletProcessInfo.ReceivedTabletNumber[tabletUnit->SuctionDiscPos];
				SPBTabletProcessInfo.ExpectedNextTabletNumber[tabletUnit->SuctionDiscPos] = tabletUnit->TabletNumber + 1;
				if (SPBTabletProcessInfo.ExpectedNextTabletNumber[tabletUnit->SuctionDiscPos] > MAX_TABLET_NUMBER)
				{
					SPBTabletProcessInfo.ExpectedNextTabletNumber[tabletUnit->SuctionDiscPos] = 1;
				}
				tabletUnit->State = SPB_TABLET_STATE_CAPTURE_READY;
				SPBTabletProcessInfo.NumberingCaptureListIndex = (SPBTabletProcessInfo.NumberingCaptureListIndex + 1) & SPB_TABLET_LIST_MASK;
				SPBTabletProcessInfo.TabletNumberRequestOn[tabletUnit->SuctionDiscPos] = 0;
			}
		}
		else if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
		{
			SPBTabletProcessInfo.NumberingCaptureListIndex = (SPBTabletProcessInfo.NumberingCaptureListIndex + 1) & SPB_TABLET_LIST_MASK;
			SPBTabletProcessInfo.TabletNumberRequestOn[tabletUnit->SuctionDiscPos] = 0;
		}		
		if (SPBTabletProcessInfo.TabletNumberReceived[tabletUnit->SuctionDiscPos])
		{
			SPBTabletProcessInfo.TabletNumberReceived[tabletUnit->SuctionDiscPos] = 0;		// processed tablet number
		}
	}

	if (SPBTabletProcessInfo.CaptureMode != MACHINE_CAPTURE_MODE_NONE)
	{
		// check capture
		tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.PollingCaptureListIndex]);
		if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
		{
			SPBTabletProcessInfo.PollingCaptureListIndex = (SPBTabletProcessInfo.PollingCaptureListIndex + 1) & SPB_TABLET_LIST_MASK;
		}
		else if (tabletUnit->State == SPB_TABLET_STATE_CAPTURE_READY)
		{
			bError = 0;
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{
				if ((CameraSetupData.CameraEnable[spbCamIndex]))// && (G_C_CAMERA_SD_POS_INFO[(int)tabletUnit->SuctionDiscPos][G_SPB_INDEX-1][spbCamIndex] == 1))
				{
					if (((IntCaptureQueue[spbCamIndex].QueueEnd + 1) & CAPTURE_QUEUE_MASK) == IntCaptureQueue[spbCamIndex].QueueStart)
					{
						bError = 1;
						break;
					}
					if(CameraSetupData.TabletType ==SUGARCOATING)
					{
						// side 1
						if((SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD1_2D_SIDE_FACE_P45_CAMERA_INDEX - 1) || (SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD2_2D_SIDE_FACE_P45_CAMERA_INDEX-1))
						{
							IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueEnd].CaptureStartTime = 
							tabletUnit->CaptureIntTime + CameraSetupData.ShutterDelay[spbCamIndex] + CAPTURE_STABLE_DELAY+(LAMP_SUGAR_TABLET_DELAY*0);					
						}//side 2
						else if((SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX - 1) || (SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD2_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX-1))
						{
							IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueEnd].CaptureStartTime = 
							tabletUnit->CaptureIntTime + CameraSetupData.ShutterDelay[spbCamIndex] + CAPTURE_STABLE_DELAY+(LAMP_SUGAR_TABLET_DELAY*1);					
						}//front
						else if((SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1) || (SystemSetupData.GlobalCameraIndex[spbCamIndex] ==SD2_2D_FRONT_FACE_CAMERA_INDEX-1))
						{
							IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueEnd].CaptureStartTime = 
							tabletUnit->CaptureIntTime + CameraSetupData.ShutterDelay[spbCamIndex] + CAPTURE_STABLE_DELAY+(LAMP_SUGAR_TABLET_DELAY*2);	
						}//side 3					
						else if((SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD1_2D_SIDE_FACE_M45_CAMERA_INDEX - 1) || (SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD2_2D_SIDE_FACE_M45_CAMERA_INDEX-1))
						{
							IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueEnd].CaptureStartTime = 
							tabletUnit->CaptureIntTime + CameraSetupData.ShutterDelay[spbCamIndex] + CAPTURE_STABLE_DELAY+(LAMP_SUGAR_TABLET_DELAY*3);				
						}//side 4
						else if((SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD1_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX - 1) || (SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD2_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX-1))
						{
							IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueEnd].CaptureStartTime = 
							tabletUnit->CaptureIntTime + CameraSetupData.ShutterDelay[spbCamIndex] + CAPTURE_STABLE_DELAY+(LAMP_SUGAR_TABLET_DELAY*4);
						}
						else 
						{
							IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueEnd].CaptureStartTime = 
								tabletUnit->CaptureIntTime + CameraSetupData.ShutterDelay[spbCamIndex] + CAPTURE_STABLE_DELAY;
						}
					}
					else
					{
						IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueEnd].CaptureStartTime = 
							tabletUnit->CaptureIntTime + CameraSetupData.ShutterDelay[spbCamIndex] + CAPTURE_STABLE_DELAY + 6;
					}
					IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueEnd].ProcessInfoListIndex = SPBTabletProcessInfo.PollingCaptureListIndex;
					IntCaptureQueue[spbCamIndex].QueueEnd = (IntCaptureQueue[spbCamIndex].QueueEnd + 1) & CAPTURE_QUEUE_MASK;
					tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_ON_CAPTURE;
				}
			}
			if (bError)
			{
				tabletUnit->Result = SPB_TABLET_RESULT_UNINS_CAPTURE_NOT_READY;
				tabletUnit->State = SPB_TABLET_STATE_ERROR;
			}
			else
			{
				tabletUnit->State = SPB_TABLET_STATE_ON_CAPTURE;
			}
			SPBTabletProcessInfo.PollingCaptureListIndex = (SPBTabletProcessInfo.PollingCaptureListIndex + 1) & SPB_TABLET_LIST_MASK;
		}		
		// capture trigger process
		for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
		{
			if (IntCaptureQueue[spbCamIndex].QueueStart != IntCaptureQueue[spbCamIndex].QueueEnd)// && Board50usTimer - int_last_capture_time > 20)
			{
				captureQueueUnit = &(IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueStart]);
				if ((int)(Board50usTimer - captureQueueUnit->CaptureStartTime) > 0)
				{
					cameraError 	= 0;
					cameraStatus 	= GetCameraStatus(spbCamIndex);

					if (cameraStatus == CAMERA_STATUS_READY)
					{
							ProcessingTimeList[captureQueueUnit->ProcessInfoListIndex].CaptureStartTime[spbCamIndex] = Board1MSTmr;
							ProcessingTimeList[captureQueueUnit->ProcessInfoListIndex].CaptureEndTime[spbCamIndex] = Board1MSTmr;
							ProcessingTimeList[captureQueueUnit->ProcessInfoListIndex].ImageSendStartTime[spbCamIndex] = Board1MSTmr;
							ProcessingTimeList[captureQueueUnit->ProcessInfoListIndex].ProcessingStartTime[spbCamIndex] = Board1MSTmr;
							ProcessingTimeList[captureQueueUnit->ProcessInfoListIndex].ProcessingEndTime[spbCamIndex] = Board1MSTmr;
							captureTabletUnit = &(SPBTabletProcessInfo.TabletList[captureQueueUnit->ProcessInfoListIndex]);
							if (NextCaptureTrigger(spbCamIndex, captureTabletUnit->CaptureImagePtr[spbCamIndex], &(captureTabletUnit->CaptureStatus[spbCamIndex])) == 0)
							{
								if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_CAPTURE)
								{
									ImageControl_CalibMode_SetBufferState(spbCamIndex, captureTabletUnit->CalibCaptureFrameIndex[spbCamIndex], IC_CALIB_STATE_ON_CAPTURE);
								}							
								int_last_capture_time = Board50usTimer;
							}
							else
							{
								if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_PROCESSING)
								{
									captureTabletUnit->Result = SPB_TABLET_RESULT_UNINS_CAPTURE_NOT_READY;
									captureTabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_CAPTURE_ERROR;
								}
								if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_CAPTURE)
								{
									ImageControl_CalibMode_SetBufferState(spbCamIndex, captureTabletUnit->CalibCaptureFrameIndex[spbCamIndex], IC_CALIB_STATE_ERROR);
									captureTabletUnit->Result = SPB_TABLET_RESULT_UNINS_CAPTURE_NOT_READY;
									captureTabletUnit->State = SPB_TABLET_STATE_ERROR;
								}
							}

					}	
					else if (cameraStatus == CAMERA_STATUS_ON_CAPTURE)
					{
						if(1)//(!SystemSetupData.Laser_complexer_Enable==1)
						{
							if (SystemSetupData.CameraKind[spbCamIndex] == CAMERA_KIND_NFA_3D)
							{
								ProcessingTimeList[captureQueueUnit->ProcessInfoListIndex].CaptureStartTime[spbCamIndex] = Board1MSTmr;
								ProcessingTimeList[captureQueueUnit->ProcessInfoListIndex].CaptureEndTime[spbCamIndex] = Board1MSTmr;
								ProcessingTimeList[captureQueueUnit->ProcessInfoListIndex].ImageSendStartTime[spbCamIndex] = Board1MSTmr;
								ProcessingTimeList[captureQueueUnit->ProcessInfoListIndex].ProcessingStartTime[spbCamIndex] = Board1MSTmr;
								ProcessingTimeList[captureQueueUnit->ProcessInfoListIndex].ProcessingEndTime[spbCamIndex] = Board1MSTmr;
								captureTabletUnit = &(SPBTabletProcessInfo.TabletList[captureQueueUnit->ProcessInfoListIndex]);
								captureTabletUnit->CaptureStatus[spbCamIndex] = CAPTURE_STATUS_NONE;
								if (NextCaptureTrigger(spbCamIndex, captureTabletUnit->CaptureImagePtr[spbCamIndex], &(captureTabletUnit->CaptureStatus[spbCamIndex])) == 0)
								{
									if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_CAPTURE)
									{
										ImageControl_CalibMode_SetBufferState(spbCamIndex, captureTabletUnit->CalibCaptureFrameIndex[spbCamIndex], IC_CALIB_STATE_ON_CAPTURE);
									}
								}
								else
								{
									cameraError = 1;								
								}
							}
							else
							{
								captureTabletUnit = &(SPBTabletProcessInfo.TabletList[captureQueueUnit->ProcessInfoListIndex]);
								captureTabletUnit->Result = SPB_TABLET_RESULT_UNINS_CAPTURE_NOT_READY;
								cameraError = 1;
							}
						}
					}
					else
					{
						cameraError = 1;						
					}

					if (cameraError)
					{
						captureTabletUnit = &(SPBTabletProcessInfo.TabletList[captureQueueUnit->ProcessInfoListIndex]);
						if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_PROCESSING)
						{
							captureTabletUnit->Result = SPB_TABLET_RESULT_UNINS_CAPTURE_NOT_READY;
							captureTabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_CAPTURE_ERROR;
						}
						else if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_CAPTURE)
						{
							ImageControl_CalibMode_SetBufferState(spbCamIndex, captureTabletUnit->CalibCaptureFrameIndex[spbCamIndex], IC_CALIB_STATE_ERROR);
							captureTabletUnit->State = SPB_TABLET_STATE_ERROR;
						}	
					}
						IntCaptureQueue[spbCamIndex].QueueStart = (IntCaptureQueue[spbCamIndex].QueueStart + 1) & CAPTURE_QUEUE_MASK;
					}
				/*
				else if (captureQueueUnit->CaptureStartTime - 1 <= Board50usTimer && (SystemSetupData.CameraKind[spbCamIndex] == CAMERA_KIND_CIS))
				{
					SetCaptureTime(spbCamIndex);
				}
				*/
			}
		}
	}
}



void Capture_Process_1ms(void)		// per 1ms
{
	int spbCamIndex;
	int tabletListIndex;
	int allCaptured;
	int captureImageIndex;
	int errorOccured;
	int bInspectComplete, bDefect, errorID;
	//int capture_timeout;
	//int bufferExist;

	//int bInspectionTimeout;
	int bProcessing, bProcessingAll;
	int bError;
	int resultCheckingIndex, resultCheckingCount;
	int waitOtherCameraResultSW;
	int bViewDefectImageForPrintResultChecking;
	short temp_dergee;
	short temp_poX,temp_poY;

	TSPBTabletUnit *tabletUnit, *nextTabletUnit;

	if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_PROCESSING)
	{
		// find buffer index
		tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.FindingBufferListIndex]);
		nextTabletUnit = &(SPBTabletProcessInfo.TabletList[(SPBTabletProcessInfo.FindingBufferListIndex + 1) & SPB_TABLET_LIST_MASK]);
		if (tabletUnit->State == SPB_TABLET_STATE_FINDING_BUFFER)
		{
			if(1)//(!SystemSetupData.Laser_complexer_Enable==1)
			{
				// all board
				tabletUnit->ImageFrameIndex = GetProcessingImageBufferIndex();	
			}
			else 
			{
				for(spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
				{
					if(SystemSetupData.CameraKind[spbCamIndex] != CAMERA_KIND_NFA_3D)
					{
						if (!CameraSetupData.CameraEnable[spbCamIndex]) continue;
						tabletUnit->ImageFrameIndex = GetProcessingImageBufferIndex();
						break;
					}
				}
			}

			if (tabletUnit->ImageFrameIndex == -1)
			{
				tabletUnit->Result = SPB_TABLET_RESULT_UNINS_IMAGE_BUFFER_FULL;
				tabletUnit->State = SPB_TABLET_STATE_ERROR;
				SPBTabletProcessInfo.FindingBufferListIndex = (SPBTabletProcessInfo.FindingBufferListIndex + 1) & SPB_TABLET_LIST_MASK;			
			}	
			else
			{
				bError = 0;
				for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
				{		
					if (!CameraSetupData.CameraEnable[spbCamIndex]) continue;

					if(1)//(!SystemSetupData.Laser_complexer_Enable==1)
					{
						tabletUnit->CaptureImagePtr[spbCamIndex] = GetProcessingImageBufferPtr(spbCamIndex, tabletUnit->ImageFrameIndex);
					}
					else					
					{
						if (SystemSetupData.CameraKind[spbCamIndex] == CAMERA_KIND_NFA_3D)
						{
							nextTabletUnit->ImageFrameIndex = GetProcessingImageBufferIndex();
							if(nextTabletUnit->ImageFrameIndex == -1) 
							{
								ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_PROCESS_RUNTIME, tabletUnit->TabletNumber, __LINE__, 9999);
								bError = 1;
								break;
							}

							nextTabletUnit->CaptureImagePtr[spbCamIndex] = GetProcessingImageBufferPtr(spbCamIndex, nextTabletUnit->ImageFrameIndex);
							if (NextCaptureTrigger(spbCamIndex, nextTabletUnit->CaptureImagePtr[spbCamIndex], &(nextTabletUnit->CaptureStatus[spbCamIndex])) == 0)
							{
								nextTabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_ON_CAPTURE;
							}
							else
							{
								if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_PROCESSING)
								{
									nextTabletUnit->Result = SPB_TABLET_RESULT_UNINS_CAPTURE_NOT_READY;
									nextTabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_CAPTURE_ERROR;
								}
							}	
							ProcessingTimeList[SPBTabletProcessInfo.FindingBufferListIndex].CaptureStartTime[spbCamIndex] = Board1MSTmr;
							ProcessingTimeList[SPBTabletProcessInfo.FindingBufferListIndex].CaptureEndTime[spbCamIndex] = Board1MSTmr;
							ProcessingTimeList[SPBTabletProcessInfo.FindingBufferListIndex].ImageSendStartTime[spbCamIndex] = Board1MSTmr;
							ProcessingTimeList[SPBTabletProcessInfo.FindingBufferListIndex].ProcessingStartTime[spbCamIndex] = Board1MSTmr;
							ProcessingTimeList[SPBTabletProcessInfo.FindingBufferListIndex].ProcessingEndTime[spbCamIndex] = Board1MSTmr;						
						}
						else
						{
							tabletUnit->CaptureImagePtr[spbCamIndex] = GetProcessingImageBufferPtr(spbCamIndex, tabletUnit->ImageFrameIndex);						
						}
					}
				}

				if(!bError)
				{
					tabletUnit->State = SPB_TABLET_STATE_NUMBERING;

					SPBTabletProcessInfo.FindingBufferListIndex = (SPBTabletProcessInfo.FindingBufferListIndex + 1) & SPB_TABLET_LIST_MASK;
				}
			}
		}

		// check capture end
		for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
		{
			tabletListIndex = SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex];
			tabletUnit = &(SPBTabletProcessInfo.TabletList[tabletListIndex]);
			if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
			{
				SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex] = (SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
			}
			else if (tabletUnit->State == SPB_TABLET_STATE_ON_CAPTURE)
			{
				if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_ON_CAPTURE)
				{	
					if (tabletUnit->CaptureStatus[spbCamIndex] == CAPTURE_STATUS_COMPLETE)
					{
						tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_CAPTURED;
						ProcessingTimeList[tabletListIndex].CaptureEndTime[spbCamIndex] = Board1MSTmr;
						SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex] = (SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
					}
					else if (tabletUnit->CaptureStatus[spbCamIndex] == CAPTURE_STATUS_TIMEOUT)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_UNINS_CAPTURE_TIMEOUT;
						tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_CAPTURE_ERROR;
						SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex] = (SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
					}
				}
				else if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_CAPTURE_ERROR)
				{
					SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex] = (SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
				}
				else if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PASSED)
				{
					SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex] = (SPBTabletProcessInfo.PollingCaptureEndListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
				}
			}
		}
		tabletListIndex = SPBTabletProcessInfo.PollingCaptureAllEndListIndex;
		tabletUnit = &(SPBTabletProcessInfo.TabletList[tabletListIndex]);
		if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
		{
			SPBTabletProcessInfo.PollingCaptureAllEndListIndex = (SPBTabletProcessInfo.PollingCaptureAllEndListIndex + 1) & SPB_TABLET_LIST_MASK;
		}
		else if (tabletUnit->State == SPB_TABLET_STATE_ON_CAPTURE)
		{
			allCaptured = 1;
			errorOccured = 0;
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{
				if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_ON_CAPTURE ||
					tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_CAPTURE_WAITING)
				{	
					allCaptured = 0;
				}
				else if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_CAPTURE_ERROR)
				{
					errorOccured = 1;
				}
			}
			if (allCaptured)
			{
				captureImageIndex = tabletUnit->ImageFrameIndex;
				if (errorOccured)
				{
					ProcessingImageBuffer_MarkCaptured(captureImageIndex);					
					for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
					{
						ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_NONE;
					}
					tabletUnit->State = SPB_TABLET_STATE_ERROR;
				}
				else
				{
					ProcessingImageBuffer_MarkCaptured(captureImageIndex);
					for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
					{
						ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_NONE;
					}
					tabletUnit->State = SPB_TABLET_STATE_CAPTURED;
				}				
				SPBTabletProcessInfo.PollingCaptureAllEndListIndex = (SPBTabletProcessInfo.PollingCaptureAllEndListIndex + 1) & SPB_TABLET_LIST_MASK;
			}
		}
	}
	else
	{
		// find buffer index
		tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.FindingBufferListIndex]);
		nextTabletUnit = &(SPBTabletProcessInfo.TabletList[(SPBTabletProcessInfo.FindingBufferListIndex+1)&SPB_TABLET_LIST_MASK]);
		if (tabletUnit->State == SPB_TABLET_STATE_FINDING_BUFFER)
		{	
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{		
				if ((!CameraSetupData.CameraEnable[spbCamIndex])) continue;// || (G_C_CAMERA_SD_POS_INFO[(int)tabletUnit->SuctionDiscPos][G_SPB_INDEX-1][spbCamIndex] == 0)) continue;

				if(0)// (SystemSetupData.CameraKind[spbCamIndex] == CAMERA_KIND_NFA_3D &&SystemSetupData.Laser_complexer_Enable ==1)
				{
					if (CaptureFrameCount - ImageControl_CalibMode_GetFilledFrameCount(spbCamIndex) < 2)
					{
						nextTabletUnit->CaptureImagePtr[spbCamIndex] = ImageControl_CalibMode_GetLastFrameBuffer(spbCamIndex);
						nextTabletUnit->CalibCaptureFrameIndex[spbCamIndex] = ImageControl_CalibMode_GetLastFrameIndex(spbCamIndex);
					}
					else
					{
						nextTabletUnit->CaptureImagePtr[spbCamIndex] = ImageControl_CalibMode_GetLastFrameBuffer(spbCamIndex);
						nextTabletUnit->CalibCaptureFrameIndex[spbCamIndex] = ImageControl_CalibMode_GetLastFrameIndex(spbCamIndex);			
						ImageControl_CalibMode_IncreaseFIFO(spbCamIndex);
					}
					if (NextCaptureTrigger(spbCamIndex, nextTabletUnit->CaptureImagePtr[spbCamIndex], &(nextTabletUnit->CaptureStatus[spbCamIndex])) == 0)
					{
						if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_CAPTURE)
						{
							ImageControl_CalibMode_SetBufferState(spbCamIndex, nextTabletUnit->CalibCaptureFrameIndex[spbCamIndex], IC_CALIB_STATE_ON_CAPTURE);
						}
						nextTabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_ON_CAPTURE;
					}
					else
					{
						return;
					}
				}
				else
				{
					if (CaptureFrameCount - ImageControl_CalibMode_GetFilledFrameCount(spbCamIndex) < 2)
					{
						tabletUnit->CaptureImagePtr[spbCamIndex] = ImageControl_CalibMode_GetLastFrameBuffer(spbCamIndex);
						tabletUnit->CalibCaptureFrameIndex[spbCamIndex] = ImageControl_CalibMode_GetLastFrameIndex(spbCamIndex);
					}
					else
					{
						tabletUnit->CaptureImagePtr[spbCamIndex] = ImageControl_CalibMode_GetLastFrameBuffer(spbCamIndex);
						tabletUnit->CalibCaptureFrameIndex[spbCamIndex] = ImageControl_CalibMode_GetLastFrameIndex(spbCamIndex);			
						ImageControl_CalibMode_IncreaseFIFO(spbCamIndex);
					}
 				}
			}
			tabletUnit->State = SPB_TABLET_STATE_CAPTURE_READY;			
			SPBTabletProcessInfo.FindingBufferListIndex = (SPBTabletProcessInfo.FindingBufferListIndex + 1) & SPB_TABLET_LIST_MASK;
		}
		tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.PollingCaptureAllEndListIndex]);
		if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
		{
			//SPBTabletProcessInfo.PollingCaptureEndListIndex = (SPBTabletProcessInfo.PollingCaptureEndListIndex + 1) & SPB_TABLET_LIST_MASK;
			SPBTabletProcessInfo.PollingCaptureAllEndListIndex = (SPBTabletProcessInfo.PollingCaptureAllEndListIndex + 1) & SPB_TABLET_LIST_MASK;
		}
		else if (tabletUnit->State == SPB_TABLET_STATE_ON_CAPTURE)
		{
			allCaptured = 1;
			errorOccured = 0;
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{
				if ((!CameraSetupData.CameraEnable[spbCamIndex])) continue;// || (G_C_CAMERA_SD_POS_INFO[(int)tabletUnit->SuctionDiscPos][G_SPB_INDEX-1][spbCamIndex] == 0)) continue;
				if (tabletUnit->CaptureStatus[spbCamIndex] == CAPTURE_STATUS_ON_CAPTURE)
				{
					allCaptured = 0;
				}
				else if (tabletUnit->CaptureStatus[spbCamIndex] == CAPTURE_STATUS_TIMEOUT)
				{
					errorOccured = 1;
					ImageControl_CalibMode_SetBufferState(spbCamIndex, tabletUnit->CalibCaptureFrameIndex[spbCamIndex], IC_CALIB_STATE_ERROR);
				}
				else if (tabletUnit->CaptureStatus[spbCamIndex] == CAPTURE_STATUS_COMPLETE)
				{
					if (SystemSetupData.CameraKind[spbCamIndex] == CAMERA_KIND_NFA_3D && SystemSetupData.Laser_complexer_Enable == 1)
					{
						if(BoardID == BOARD_ID_SPB(7) & test_Laser_MC_Status ==0)
						{
							temp_poX = SystemSetupData.LaserPositionCalData[0]*LaserCalInPutDataX-SystemSetupData.LaserPositionCalData[2]*LaserCalInPutDataY;
							temp_poY = SystemSetupData.LaserPositionCalData[3]*LaserCalInPutDataY-SystemSetupData.LaserPositionCalData[1]*LaserCalInPutDataX;
							LaserMcbsp_SendPacket(0, temp_poY,temp_poX);
						}
					}
					ImageControl_CalibMode_SetBufferState(spbCamIndex, tabletUnit->CalibCaptureFrameIndex[spbCamIndex], IC_CALIB_STATE_CAPTURE_COMPLETE);
				}
				else // capture ready
				{
					allCaptured = 0;
				}
			}
			if (allCaptured)
			{				
				if (errorOccured)
				{
					tabletUnit->State = SPB_TABLET_STATE_ERROR;
				}
				else
				{
					tabletUnit->State = SPB_TABLET_STATE_NONE;
				}										
				SPBTabletProcessInfo.PollingCaptureAllEndListIndex = (SPBTabletProcessInfo.PollingCaptureAllEndListIndex + 1) & SPB_TABLET_LIST_MASK;
			}		
		}
	}
	if (SPBTabletProcessInfo.CaptureMode != MACHINE_CAPTURE_MODE_NONE)
	{
/*
		// check capture
		tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.PollingCaptureListIndex]);
		if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
		{
			SPBTabletProcessInfo.PollingCaptureListIndex = (SPBTabletProcessInfo.PollingCaptureListIndex + 1) & SPB_TABLET_LIST_MASK;
		}
		else if (tabletUnit->State == SPB_TABLET_STATE_CAPTURE_READY)
		{
			bError = 0;
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{
				if ((CameraSetupData.CameraEnable[spbCamIndex]))// && (G_C_CAMERA_SD_POS_INFO[(int)tabletUnit->SuctionDiscPos][G_SPB_INDEX-1][spbCamIndex] == 1))
				{
					if (((IntCaptureQueue[spbCamIndex].QueueEnd + 1) & CAPTURE_QUEUE_MASK) == IntCaptureQueue[spbCamIndex].QueueStart)
					{
						bError = 1;
						break;
					}
					// add capture queue
					IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueEnd].CaptureStartTime = 
						tabletUnit->CaptureIntTime + CameraSetupData.ShutterDelay[spbCamIndex] + CAPTURE_STABLE_DELAY;
					IntCaptureQueue[spbCamIndex].List[IntCaptureQueue[spbCamIndex].QueueEnd].ProcessInfoListIndex = SPBTabletProcessInfo.PollingCaptureListIndex;
					IntCaptureQueue[spbCamIndex].QueueEnd = (IntCaptureQueue[spbCamIndex].QueueEnd + 1) & CAPTURE_QUEUE_MASK;
					tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_ON_CAPTURE;
				}
			}
			if (bError)
			{
				tabletUnit->Result = SPB_TABLET_RESULT_UNINS_CAPTURE_NOT_READY;
				tabletUnit->State = SPB_TABLET_STATE_ERROR;
			}
			else
			{
				tabletUnit->State = SPB_TABLET_STATE_ON_CAPTURE;
			}
			SPBTabletProcessInfo.PollingCaptureListIndex = (SPBTabletProcessInfo.PollingCaptureListIndex + 1) & SPB_TABLET_LIST_MASK;
		}
*/
	}

	if (SPBTabletProcessInfo.ProcessingMode == TABLET_PROCESSING_MODE_INSPECTION || SPBTabletProcessInfo.ProcessingMode == TABLET_PROCESSING_MODE_STUDY)
	{
		for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
		{
			tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.processingPositionListIndex[spbCamIndex]]);
			if (tabletUnit->State == SPB_TABLET_STATE_ON_CAPTURE || tabletUnit->State == SPB_TABLET_STATE_CAPTURED)
			{
				if ((SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1) &&SystemSetupData.Laser_complexer_Enable == 1)
				{
					if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_CAPTURED)
					{
						tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_POSITION_READY;
					}			
					else if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PASSED ||
						tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_CAPTURE_ERROR ||
						tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_POSITION_PROCESSING ||
						tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_POSITION_PROCESSING_ERROR)
					{
						SPBTabletProcessInfo.processingPositionListIndex[spbCamIndex] = (SPBTabletProcessInfo.processingPositionListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
					}
				}
				else
				{
					if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_CAPTURED)
					{
						tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_POSITION_PROCESSING_COMPLETE;
						SPBTabletProcessInfo.processingPositionListIndex[spbCamIndex] = (SPBTabletProcessInfo.processingPositionListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
					}
				}
			}
			else if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
			{
				SPBTabletProcessInfo.processingPositionListIndex[spbCamIndex] = (SPBTabletProcessInfo.processingPositionListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
			}
		}
		
		tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.ProcessingAllPositionListIndex]);
		if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
		{
			SPBTabletProcessInfo.ProcessingAllPositionListIndex = (SPBTabletProcessInfo.ProcessingAllPositionListIndex + 1) & SPB_TABLET_LIST_MASK;
		}
		else if (tabletUnit->State == SPB_TABLET_STATE_CAPTURED)
		{
			bProcessingAll = 1;
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{
				if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_CAPTURED ||
					tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_POSITION_READY)
				{
					bProcessingAll = 0;
				}
			}
			if (bProcessingAll)
			{
				tabletUnit->State = SPB_TABLET_STATE_GET_POSITION;
				SPBTabletProcessInfo.ProcessingAllPositionListIndex = (SPBTabletProcessInfo.ProcessingAllPositionListIndex + 1) & SPB_TABLET_LIST_MASK;
			}
		}

		if(SystemSetupData.Laser_complexer_Enable == 1 && test_Laser_MC_Status == 0)
		{
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{
				tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.ProcessingTabletListIndex[spbCamIndex]]);
				if (tabletUnit->State >= SPB_TABLET_STATE_CAPTURED && tabletUnit->State < SPB_TABLET_STATE_PROCESSING)
				{
					if (SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1)
					{
						Max3DResultWaitingTime = tabletUnit->CaptureIntTime + Max_Laser_Position_Processing_Time - LASER_STABLE_WAITING_TIME_50US;
						
						if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_POSITION_READY || 
							tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_POSITION_PROCESSING)
						{
							if(Board50usTimer >= (Max3DResultWaitingTime))
							{
								ThreeDPositionInfo_SPB.TabletRotationAngle = 0;
								ThreeDPositionInfo_SPB.TabletCenterX = 0xFFFF;
								ThreeDPositionInfo_SPB.TabletCenterY = 0xFFFF;
								MakeLaserQueueData((ThreeDPositionInfo_SPB.TabletRotationAngle) * 100, ThreeDPositionInfo_SPB.TabletCenterX, ThreeDPositionInfo_SPB.TabletCenterY, Max3DResultWaitingTime);
								tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_POSITION_PROCESSING_COMPLETE;
								tabletUnit->Result = SPB_TABLET_RESULT_UNINS_PROCESSING_TIMEOUT;
								tabletUnit->State = SPB_TABLET_STATE_ERROR;	
								ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_CPB_PROCESS_TIMEOUT, tabletUnit->TabletNumber,Max3DResultWaitingTime-tabletUnit->CaptureIntTime,Board50usTimer-tabletUnit->CaptureIntTime);
							}
						}
						else if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_POSITION_PROCESSING_COMPLETE)
						{
							temp_dergee = ThreeDPositionInfo_SPB.TabletRotationAngle;

							if(temp_dergee > 180) temp_dergee = 360 - temp_dergee; // -180~180 으로 범위 변경

							if((abs(ThreeDPositionInfo_SPB.TabletCenterX) > TabletGradeData_SPB.LaserAllowX) && (TabletGradeData_SPB.LaserAllowX !=0)) 
							{
								ThreeDPositionInfo_SPB.TabletRotationAngle = 0;
								ThreeDPositionInfo_SPB.TabletCenterX = 0xFFFF;
								ThreeDPositionInfo_SPB.TabletCenterY = 0xFFFF;
							}
							
							if((abs(ThreeDPositionInfo_SPB.TabletCenterY) > TabletGradeData_SPB.LaserAllowY) && (TabletGradeData_SPB.LaserAllowY !=0))
							{
								ThreeDPositionInfo_SPB.TabletRotationAngle = 0;
								ThreeDPositionInfo_SPB.TabletCenterX = 0xFFFF;
								ThreeDPositionInfo_SPB.TabletCenterY = 0xFFFF;								
							}
							
							if((abs(temp_dergee) > (TabletGradeData_SPB.LaserAllowDegree*5)) && (TabletGradeData_SPB.LaserAllowDegree !=0) )	
							{
								ThreeDPositionInfo_SPB.TabletRotationAngle = 0;
								ThreeDPositionInfo_SPB.TabletCenterX = 0xFFFF;
								ThreeDPositionInfo_SPB.TabletCenterY = 0xFFFF;								
							}
							
							if((unsigned short)ThreeDPositionInfo_SPB.TabletCenterX == 0xFFFF  && (unsigned short)ThreeDPositionInfo_SPB.TabletCenterY == 0xFFFF && ThreeDPositionInfo_SPB.TabletRotationAngle==0)
							{
								ThreeDPositionInfo_SPB.TabletRotationAngle = 0;
								ThreeDPositionInfo_SPB.TabletCenterX = 0xFFFF;
								ThreeDPositionInfo_SPB.TabletCenterY = 0xFFFF;									
							}
							else 
							{
								temp_poX = ThreeDPositionInfo_SPB.TabletCenterX*46.86;
								temp_poY = ThreeDPositionInfo_SPB.TabletCenterY*46.86;
								ThreeDPositionInfo_SPB.TabletRotationAngle = (360 -ThreeDPositionInfo_SPB.TabletRotationAngle);
								ThreeDPositionInfo_SPB.TabletCenterX = SystemSetupData.LaserPositionCalData[0]*temp_poX-SystemSetupData.LaserPositionCalData[2]*temp_poY;
								ThreeDPositionInfo_SPB.TabletCenterY = SystemSetupData.LaserPositionCalData[3]*temp_poY-SystemSetupData.LaserPositionCalData[1]*temp_poX;
							}
//							MakeLaserQueueData((ThreeDPositionInfo_SPB.TabletRotationAngle) * 85,ThreeDPositionInfo_SPB.TabletCenterY, ThreeDPositionInfo_SPB.TabletCenterX-((ThreeDPositionInfo_SPB.TabletCenterZ-120)*100), Max3DResultWaitingTime);
							MakeLaserQueueData((ThreeDPositionInfo_SPB.TabletRotationAngle) * 100,ThreeDPositionInfo_SPB.TabletCenterY, ThreeDPositionInfo_SPB.TabletCenterX, Max3DResultWaitingTime);
//							ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_CPB_PROCESS_TIMEOUT, tabletUnit->TabletNumber,ThreeDPositionInfo_SPB.TabletCenterX,ThreeDPositionInfo_SPB.TabletCenterX-((ThreeDPositionInfo_SPB.TabletCenterZ-120)*60));
						}
					}
				}
			}
		}
		
		for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
		{
			tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.ProcessingTabletListIndex[spbCamIndex]]);
			if (tabletUnit->State == SPB_TABLET_STATE_GET_POSITION)
			{
				if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_POSITION_PROCESSING_COMPLETE)
				{
					if (tabletUnit->Result == SPB_TABLET_RESULT_NONE)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_PROCESSING;
					}

					tabletUnit->ProcessingStartTime[spbCamIndex] = Board1MSTmr;
					tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_PROCESSING_READY;
				}
				else if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PASSED ||
					tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_CAPTURE_ERROR ||
					tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING ||
					tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_ERROR)
				{
					SPBTabletProcessInfo.ProcessingTabletListIndex[spbCamIndex] = (SPBTabletProcessInfo.ProcessingTabletListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
				}
			}
			else if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
			{
				SPBTabletProcessInfo.ProcessingTabletListIndex[spbCamIndex] = (SPBTabletProcessInfo.ProcessingTabletListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
			}
		}

		
		tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.ProcessingAllTabletListIndex]);
		if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
		{
			SPBTabletProcessInfo.ProcessingAllTabletListIndex = (SPBTabletProcessInfo.ProcessingAllTabletListIndex + 1) & SPB_TABLET_LIST_MASK;
		}
		else if (tabletUnit->State ==SPB_TABLET_STATE_GET_POSITION)
		{
			bProcessingAll = 1;
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{
				if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_CAPTURED ||
					tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_POSITION_PROCESSING ||
					tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_READY)
				{
					bProcessingAll = 0;
				}
			}
			if (bProcessingAll)
			{
				tabletUnit->State = SPB_TABLET_STATE_PROCESSING;
				SPBTabletProcessInfo.ProcessingAllTabletListIndex = (SPBTabletProcessInfo.ProcessingAllTabletListIndex + 1) & SPB_TABLET_LIST_MASK;
			}
		}
	}
	if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_PROCESSING)
	{
		// checking processing complete
		for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
		{
			tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.ProcessingResultListIndex[spbCamIndex]]);
			if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
			{
				SPBTabletProcessInfo.ProcessingResultListIndex[spbCamIndex] = (SPBTabletProcessInfo.ProcessingResultListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
			}
			else if (tabletUnit->State == SPB_TABLET_STATE_ON_CAPTURE || tabletUnit->State == SPB_TABLET_STATE_CAPTURED ||
				tabletUnit->State == SPB_TABLET_STATE_PROCESSING)
			{
				if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PASSED ||
					tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_CAPTURE_ERROR ||
					tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_ERROR)
				{
					SPBTabletProcessInfo.ProcessingResultListIndex[spbCamIndex] = (SPBTabletProcessInfo.ProcessingResultListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
				}
				else if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING)
				{
					bProcessing = 1;
					if (Board1MSTmr - tabletUnit->ProcessingStartTime[spbCamIndex] > PROCESSING_TIMEOUT)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_UNINS_PROCESSING_TIMEOUT;
						tabletUnit->State = SPB_TABLET_STATE_ERROR;
						//ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_PROCESS_RUNTIME, tabletUnit->ProcessingStartTime[spbCamIndex], PROCESSING_TIMEOUT, 7777);
						SPBTabletProcessInfo.ProcessingResultListIndex[spbCamIndex] = (SPBTabletProcessInfo.ProcessingResultListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
					}
				}

				else if (tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
				{	
					SPBTabletProcessInfo.ProcessingResultListIndex[spbCamIndex] = (SPBTabletProcessInfo.ProcessingResultListIndex[spbCamIndex] + 1) & SPB_TABLET_LIST_MASK;
				}
			}
		}
		resultCheckingIndex = SPBTabletProcessInfo.ProcessingResultCheckingListIndex;
		for (resultCheckingCount = 0; resultCheckingCount < 10; resultCheckingCount++)
		{
			tabletUnit = &(SPBTabletProcessInfo.TabletList[resultCheckingIndex]);
			if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
			{
				if (resultCheckingCount == 0)	// resultCheckingIndex == ProcessingResultCheckingListIndex
				{
					if (tabletUnit->ImageFrameIndex != -1)
					{
						ProcessingImageBuffer_Clear(tabletUnit->ImageFrameIndex);
					}
					ProcessingTimeList[resultCheckingIndex].CompleteTime = Board1MSTmr;
					SPBTabletProcessInfo.ProcessingResultCheckingListIndex = (SPBTabletProcessInfo.ProcessingResultCheckingListIndex + 1) & SPB_TABLET_LIST_MASK;
				}
			}
/*
			else if (tabletUnit->State == SPB_TABLET_STATE_PROCESSING)
			{
				bViewDefectImageForPrintResultChecking = 0;
				waitOtherCameraResultSW = 0;
				bInspectComplete = 1;
				bDefect = 0;
				errorID = 0;
				captureImageIndex = tabletUnit->ImageFrameIndex;

				for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
				{
					if ((!CameraSetupData.CameraEnable[spbCamIndex])) continue;
					{
						if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_UNKNOWN)
						{
							bInspectComplete = 0;					
						}
					}
				}

				if(bInspectComplete)
				{
					//2021-05-04
					//bInspectComplete	조건 추가				
					//모든 카메라의 검사가 종료되어야 unit에 대한 결과 판정을 진행하는 방식으로 변경
					//불량이 발생한 카메라의 이미지를 모두 업로드하기 위함 (SearchDefectImage 함수에서 검사가 먼저 종료된 카메라가 있는 경우 다른카메라의 검사 결과에 따른 이미지 업로드가 Skip처리됨)

					for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
					{
						if ((!CameraSetupData.CameraEnable[spbCamIndex])) continue;
						{
							if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_DEFECT &&
									tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
							{
								ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
								ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
								bDefect = 1;
							}
							else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_ERROR)
							{
								errorID = 1;
							}
							else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_CPB_FULL)
							{
								errorID = 2;
							}
							else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_CLOSED_TABLET &&
									tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
							{
								ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
								ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
								errorID = 3;
							}
							else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_UNINS_TABLET_POSITION &&
									tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
							{
								ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
								ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
								errorID = 4;
							}
							else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_UNINS_BRIGHTNESS_DROPPED &&
									tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
							{
								ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
								ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
								errorID = 5;
							}
							else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_UNINS_BRIGHTNESS_CHASE &&
									tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
							{
								errorID = 6;
							}
							else if((tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_THIN_TABLET ||
									tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_FAT_TABLET) &&
									tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
							{
								ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
								ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
								errorID = 7;
								waitOtherCameraResultSW = 1;
							}

							if(InspectData_SPB.LaserStatus && TabletGradeData_SPB.EngravePositionDefectCheckSW && TabletCharacter_SPB.discriminationDisplay_kind == PRINT)
							{
								if(SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1)
								{
									if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_GOOD && tabletUnit->PrintResult[spbCamIndex] == 0)
									{
										// Laser 장비에서 Disk1 2D 정면 카메라의 cpb 결과가 good & none print 상태인 경우 미인쇄 상태에 대한 이미지를 UI에 표시하기 위함
										ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
										ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
										bViewDefectImageForPrintResultChecking = 1;
									}
								}
							}
						}
					}
				}
*/

			else if (tabletUnit->State == SPB_TABLET_STATE_PROCESSING)
			{
				bViewDefectImageForPrintResultChecking = 0;
				waitOtherCameraResultSW = 0;
				bInspectComplete = 1;
				bDefect = 0;
				errorID = 0;
				captureImageIndex = tabletUnit->ImageFrameIndex;
				for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
				{
					if ((!CameraSetupData.CameraEnable[spbCamIndex])) continue;
					{
						if(tabletUnit->InspectionState[spbCamIndex] != TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
						{
							bInspectComplete = 0;					
						}
					}
				}				
				for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
				{
					if ((!CameraSetupData.CameraEnable[spbCamIndex])) continue;
					{
						if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_UNKNOWN)
						{
							bInspectComplete = 0;					
						}
						else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_DEFECT) //&&tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
						{
							ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
							ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
							bDefect = 1;
						}
						else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_ERROR)
						{
							errorID = 1;
						}
						else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_CPB_FULL)
						{
							errorID = 2;
						}
						else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_CLOSED_TABLET &&
								tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
						{
							ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
							ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
							errorID = 3;
						}
						else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_UNINS_TABLET_POSITION &&
								tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
						{
							ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
							ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
							errorID = 4;
						}
						else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_UNINS_BRIGHTNESS_DROPPED &&
								tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
						{
							ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
							ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
							errorID = 5;
						}
						else if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_UNINS_BRIGHTNESS_CHASE &&
								tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
						{
							errorID = 6;
						}
						else if((tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_THIN_TABLET ||
								tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_FAT_TABLET) &&
								tabletUnit->InspectionState[spbCamIndex] == TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)
						{
							ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
							ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
							errorID = 7;
							waitOtherCameraResultSW = 1;
						}

						if((SystemSetupData.Laser_complexer_Enable==1) && TabletGradeData_SPB.EngravePositionDefectCheckSW && TabletCharacter_SPB.discriminationDisplay_kind == PRINT)
						{
							if(SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1)
							{
								if(tabletUnit->ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_GOOD && tabletUnit->PrintResult[spbCamIndex] == 0)
								{
									// Laser 장비에서 Disk1 2D 정면 카메라의 cpb 결과가 good & none print 상태인 경우 미인쇄 상태에 대한 이미지를 UI에 표시하기 위함
									ProcessingImageInfo.TabletNumber[captureImageIndex] = tabletUnit->TabletNumber;
									ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_DEFECT;
									bViewDefectImageForPrintResultChecking = 1;
								}
							}
						}
					}
				}
				// 2020-09-11
				// waitOtherCameraResultSW
				// 3D 카메라에서 두께불량으로 처리되는 경우 spb에서는 최종 결과를 Complete 처리해버림
				// 3D 카메라가 다른 카메라보다 결과가 늦게 발생하는 경우에는 상관이 없으나
				// 다른 카메라보다 3D 카메라의 검사 결과가 빠르게 리턴되는 경우에는
				// HCB에서 나머지 카메라의 검사 결과에 관계없이 해당 정제를 양품 판정할 수 있다. (두께불량은 DISK1, 2에서 모두 불량 판정해야 최종적으로 불량으로 처리됨)
				if (bInspectComplete || bDefect || (errorID && !waitOtherCameraResultSW))
				{
					if (bDefect)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_DEFECT;						
						ProcessingImageBuffer_MarkDefect(captureImageIndex);

						// 불량판정이 난 경우 Thick Error를 check하지 않는다
						if(errorID == 7)
						{
							for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
							{
								if (SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1 || 
									SystemSetupData.GlobalCameraIndex[spbCamIndex] == SD2_3D_FRONT_FACE_CAMERA_INDEX - 1) // 3D
								{
									tabletUnit->ThickErrorSW[spbCamIndex] = 0;
									ProcessingImageInfo.ImageInspectState[captureImageIndex][spbCamIndex] = IMAGE_RESULT_GOOD;
								}
							}
						}
					}
					else if (errorID == 1)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_UNINS_PROCESSING_ERROR;
						ProcessingImageBuffer_Clear(captureImageIndex);
					}
					else if (errorID == 2)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_UNINS_CPB_FULL;
						ProcessingImageBuffer_Clear(captureImageIndex);
					}
					else if (errorID == 3)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_UNINS_CLOSED_TABLET;
						ProcessingImageBuffer_MarkDefect(captureImageIndex);
					}
					else if (errorID == 4)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_UNINS_TABLET_POSITION;
						ProcessingImageBuffer_MarkDefect(captureImageIndex);
					}
					else if (errorID == 5)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_UNINS_BRIGHTNESS_DROPPED;
						ProcessingImageBuffer_MarkDefect(captureImageIndex);
					}
					else if (errorID == 6)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_UNINS_BRIGHTNESS_CHASE;
						ProcessingImageBuffer_Clear(captureImageIndex);
					}
					else if (errorID == 7)
					{
						tabletUnit->Result = SPB_TABLET_RESULT_GOOD;
						ProcessingImageBuffer_MarkDefect(captureImageIndex);
					}
					else 
					{
						tabletUnit->Result = SPB_TABLET_RESULT_GOOD;
						if(bViewDefectImageForPrintResultChecking)
						{
							ProcessingImageBuffer_MarkDefect(captureImageIndex);						
						}
						else
						{
							ProcessingImageBuffer_Clear(captureImageIndex);
						}
					}

					tabletUnit->State = SPB_TABLET_STATE_PROCESSING_COMPLETE;
					ProcessingTimeList[resultCheckingIndex].CompleteTime = Board1MSTmr;
				}

				if (tabletUnit->Result != SPB_TABLET_RESULT_PROCESSING && tabletUnit->Result != SPB_TABLET_RESULT_NONE)
				{
					if (resultCheckingCount == 0)
					{
						SPBTabletProcessInfo.ProcessingResultCheckingListIndex = (SPBTabletProcessInfo.ProcessingResultCheckingListIndex + 1) & SPB_TABLET_LIST_MASK;
					}
				}
			}
			else if (tabletUnit->State == SPB_TABLET_STATE_PROCESSING_COMPLETE)
			{
				if (resultCheckingCount == 0)
				{
					SPBTabletProcessInfo.ProcessingResultCheckingListIndex = (SPBTabletProcessInfo.ProcessingResultCheckingListIndex + 1) & SPB_TABLET_LIST_MASK;
				}
			}
			resultCheckingIndex = (resultCheckingIndex + 1) & SPB_TABLET_LIST_MASK;
		}
	}
}

void IntCapture_Init(void)
{
	CSL_Status status;
	ClearCaptureProcessingData();

	SPBTabletProcessInfo.CaptureMode = MACHINE_CAPTURE_MODE_NONE;
	SPBTabletProcessInfo.ProcessingMode = TABLET_PROCESSING_MODE_NONE;
	CSL_intcInterruptEnable(CSL_INTC_VECTID_4);
	SetGPIO_DH(0x0400);
}


void ProcessExternalCapture(int SuctionPos)
{
	int spbCamIndex;
	TSPBTabletUnit *tabletUnit, *nextTabletUnit;

	tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.NextCaptureListIndex]);
	
	tabletUnit->SuctionDiscPos = SuctionPos;

	if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_PROCESSING)
	{
		// check next unit's state
		nextTabletUnit = &(SPBTabletProcessInfo.TabletList[(SPBTabletProcessInfo.NextCaptureListIndex + 1) & SPB_TABLET_LIST_MASK]);
		if (nextTabletUnit->State == SPB_TABLET_STATE_NONE || nextTabletUnit->State == SPB_TABLET_STATE_ERROR ||
			nextTabletUnit->State == SPB_TABLET_STATE_PROCESSING_COMPLETE)
		{
			// clear next unit
			nextTabletUnit->State = SPB_TABLET_STATE_NONE;
			nextTabletUnit->Result = SPB_TABLET_RESULT_NONE;
			nextTabletUnit->ResultReported = 0;
			nextTabletUnit->ImageFrameIndex = -1;
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{
				nextTabletUnit->CaptureStatus[spbCamIndex] = CAPTURE_STATUS_NONE;
				nextTabletUnit->ProcessingResult[spbCamIndex] = TABLET_PROCESSING_RESULT_UNKNOWN;
				nextTabletUnit->PrintResult[spbCamIndex] =  0;
				nextTabletUnit->PrintType[spbCamIndex] = -1; // PrintType 0 = 첫번째 각인, 1 = 두번째 각인
				nextTabletUnit->ThickErrorSW[spbCamIndex] = 0;
			}
			// process hcb's capture interrupt
			tabletUnit->CaptureIntTime = Board50usTimer;
			tabletUnit->TabletNumber = 0;
			tabletUnit->State = SPB_TABLET_STATE_FINDING_BUFFER;
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{
				if ((CameraSetupData.CameraEnable[spbCamIndex]))// && (G_C_CAMERA_SD_POS_INFO[(int)tabletUnit->SuctionDiscPos][G_SPB_INDEX-1][spbCamIndex] == 1))
				{
					if(0)// (SystemSetupData.CameraKind[spbCamIndex] == CAMERA_KIND_NFA_3D && SystemSetupData.Laser_complexer_Enable==1)
					{
						tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_ON_CAPTURE;						
					}
					else
					{
						tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_CAPTURE_WAITING;
					}
					tabletUnit->ProcessingResult[spbCamIndex] = TABLET_PROCESSING_RESULT_UNKNOWN;
					tabletUnit->PrintResult[spbCamIndex] = 0;
					tabletUnit->PrintType[spbCamIndex] = -1;
				}
				else
				{
					tabletUnit->InspectionState[spbCamIndex] = TABLET_INSPECTION_STATE_PASSED;
					tabletUnit->ProcessingResult[spbCamIndex] = TABLET_PROCESSING_RESULT_GOOD;
					tabletUnit->PrintResult[spbCamIndex] = 2;
					tabletUnit->PrintType[spbCamIndex] = 2;
				}
			}
			SPBTabletProcessInfo.NextCaptureListIndex = (SPBTabletProcessInfo.NextCaptureListIndex + 1) & SPB_TABLET_LIST_MASK;
			SPBTabletProcessInfo.TabletNumberRequestOn[tabletUnit->SuctionDiscPos] = 1;
			SPBTabletProcessInfo.TabletNumberReceived[tabletUnit->SuctionDiscPos] = 0;
		}/* sjm del For RunTime
		else	// tablet list overflowed
		{
			// just skip it
		}*/
	}
	else if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_CAPTURE)
	{
		// check next unit's state
		nextTabletUnit = &(SPBTabletProcessInfo.TabletList[(SPBTabletProcessInfo.NextCaptureListIndex + 1) & SPB_TABLET_LIST_MASK]);
		if (nextTabletUnit->State == SPB_TABLET_STATE_NONE || nextTabletUnit->State == SPB_TABLET_STATE_ERROR ||
			nextTabletUnit->State == SPB_TABLET_STATE_PROCESSING_COMPLETE)
		{
			// clear next unit
			nextTabletUnit->State = SPB_TABLET_STATE_NONE;
			nextTabletUnit->Result = SPB_TABLET_RESULT_NONE;
			for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
			{
				nextTabletUnit->CaptureStatus[spbCamIndex] = CAPTURE_STATUS_NONE;
			}
			// process hcb's capture interrupt
			tabletUnit->CaptureIntTime = Board50usTimer;
			tabletUnit->TabletNumber = 0;
			tabletUnit->State = SPB_TABLET_STATE_FINDING_BUFFER;
			SPBTabletProcessInfo.NextCaptureListIndex = (SPBTabletProcessInfo.NextCaptureListIndex + 1) & SPB_TABLET_LIST_MASK;
		}/* sjm del For RunTime
		else	// tablet list overflowed
		{
			// just skip it
		}*/
	}
}

extern unsigned char bEdmaTransferStart;		//4번 카메라 EDMA transfer trigger flag ( 0 : EDMA 전송 불가능 / 1 : EDMA 전송 가능)
extern EDMA_Handle CaptureEDMAHandle[SYSTEM_SPB_CAMERA_COUNT];

void IsrIntMakeUnit_SD1(void)
{	
	int spbCamIndex;
	trgCount1++;
	
	for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
	{
		if((SystemSetupData.GlobalCameraIndex[spbCamIndex] >= 8) && (CameraSetupData.CameraEnable[spbCamIndex]!=0)) return;
	}	
	ProcessExternalCapture(SD1);
	Lamp2Toggle();
}
void IsrIntMakeUnit_SD2(void)
{
	int spbCamIndex;
	trgCount2++;

	for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
	{
		if((SystemSetupData.GlobalCameraIndex[spbCamIndex] <8) && (CameraSetupData.CameraEnable[spbCamIndex]!=0))
		{
			return;
		}
	}		
	ProcessExternalCapture(SD2);
	Lamp2Toggle();
}

void testIntCapture(int gpio)
{	
	if (gpio & 0x4000)
	{
		if (BoardID == BOARD_ID_SPB(1) || BoardID == BOARD_ID_SPB(2) || BoardID == BOARD_ID_SPB(3))
		{
			ProcessExternalCapture(SD1);
			Lamp2Toggle();
		}
	}
	else if (gpio & 0x8000)
	{
		if (BoardID == BOARD_ID_SPB(4) || BoardID == BOARD_ID_SPB(5) || BoardID == BOARD_ID_SPB(6))
		{
			ProcessExternalCapture(SD2);
			Lamp2Toggle();
		}
	}
}

void ClearIntCapture(void)
{
	SetGPIO_DH(0xC000);
}

void ResetIntCapture(void)
{
//	IRQ_disable(IRQ_EVT_GPINT0);	
//    IRQ_reset(IRQ_EVT_GPINT0);
//    IRQ_enable(IRQ_EVT_GPINT0);

//	CSL_intcEventDisable(CSL_INTC_EVENTID_GPINT10);
//	CSL_intcEventClear(CSL_INTC_EVENTID_GPINT10);
//	CSL_intcEventEnable(CSL_INTC_EVENTID_GPINT10);
	SetGPIO_DH(0xC000);
}

void TabletCapture_CaptureMode(int captureMode, int frameBufferCount, unsigned char cameraMask,
	unsigned short *shutterSpeed, unsigned short *shutterDelay, unsigned short *triggerFreq, unsigned char *SubsamplingMode, int stopCaptureSW,int TabletType,int SensorLength)
{
	int camIndex;
	unsigned char *imageBuffer;
	SPBTabletProcessInfo.CaptureMode = MACHINE_CAPTURE_MODE_CAPTURE;
	SPBTabletProcessInfo.ProcessingMode = TABLET_PROCESSING_MODE_CALIBRATION;
	ClearCaptureProcessingData();	
	
	for (camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; camIndex++)
	{
		CameraSetupData.CaptureMode = captureMode;
		CameraSetupData.FrameBufferCount = frameBufferCount;
		if (cameraMask & (0x01 << camIndex))
		{
			CameraSetupData.CameraEnable[camIndex] = 1;				
			CameraSetupData.ShutterDelay[camIndex] = shutterDelay[camIndex];
			CameraSetupData.ShutterSpeed[camIndex] = shutterSpeed[camIndex];
			CameraSetupData.TriggerFreq[camIndex] = triggerFreq[camIndex];
			CameraSetupData.SubsamplingMode[camIndex] = SubsamplingMode[camIndex];
			if(camIndex == 0)
				imageBuffer = ImageBuffer1;
			else if(camIndex == 1)
				imageBuffer = ImageBuffer2;
			else if(camIndex == 2)
				imageBuffer = ImageBuffer3;
			else if(camIndex == 3)
				imageBuffer = ImageBuffer4;

			SelectedImageControl_ClearBuffer(imageBuffer);		
		}
		else
		{
			CameraSetupData.CameraEnable[camIndex] = 0;
			CameraSetupData.ShutterDelay[camIndex] = 0;
			CameraSetupData.ShutterSpeed[camIndex] = 20;
			CameraSetupData.TriggerFreq[camIndex] = triggerFreq[camIndex];
			CameraSetupData.SubsamplingMode[camIndex] = 0;
		}
		SetImageControlMode(camIndex, IMAGE_CONTROL_MODE_FIFO);
	}
	ImageControl_CalibMode_Clear();
	CaptureFrameCount = CameraSetupData.FrameBufferCount;
	CameraSetupData.TabletType = TabletType;
	if(SensorLength)
	{
		CameraSetupData.SensorLength = SensorLength;
	}
	else
	{
		CameraSetupData.SensorLength = 1000;
	}
	CaptureSetup(CameraSetupData.ShutterSpeed, CameraSetupData.TriggerFreq, CameraSetupData.SubsamplingMode, stopCaptureSW);
	if(0)//(stopCaptureSW && SystemSetupData.Laser_complexer_Enable==1)
	{
		// 정?캡쳐인 경우 3D capture trigger 적용
		for (camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; camIndex++)
		{
			if (cameraMask & (0x01 << camIndex))
			{
				if (SystemSetupData.CameraKind[camIndex] == CAMERA_KIND_NFA_3D)
				{
					EnabledThreeDCameraSensor(camIndex, CameraSetupData.TriggerFreq[camIndex], 0);				
				}			
			}		
		}
	}
	err1_cnt = 0;
	ResetIntCapture();
}

void TabletCapture_StudyMode()
{
	int camIndex;
	unsigned char *imageBuffer;
	SPBTabletProcessInfo.CaptureMode = MACHINE_CAPTURE_MODE_PROCESSING;
	SPBTabletProcessInfo.ProcessingMode = TABLET_PROCESSING_MODE_STUDY;

	ClearCaptureProcessingData();
	for (camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; camIndex++)
	{
		if (StudySetupData_SPB.CamMask& (0x0001 << camIndex))
		{
			CameraSetupData.CameraEnable[camIndex] = 1;
			CameraSetupData.ShutterDelay[camIndex] = StudySetupData_SPB.ShutterDelay[camIndex];
			CameraSetupData.ShutterSpeed[camIndex] = StudySetupData_SPB.ShutterSpeed[camIndex];
			CameraSetupData.TriggerFreq[camIndex] = StudySetupData_SPB.TriggerFreq[camIndex];
			CameraSetupData.SubsamplingMode[camIndex] =StudySetupData_SPB.SubSamplingMode[camIndex];
			SetImageControlMode(camIndex, IMAGE_CONTROL_MODE_PROCESSING);
			if(camIndex == 0)
				imageBuffer = ImageBuffer1;
			else if(camIndex == 1)
				imageBuffer = ImageBuffer2;
			else if(camIndex == 2)
				imageBuffer = ImageBuffer3;
			else if(camIndex == 3)
				imageBuffer = ImageBuffer4;

			SelectedImageControl_ClearBuffer(imageBuffer);			
		}
		else
		{
			CameraSetupData.CameraEnable[camIndex] = 0;
			CameraSetupData.ShutterDelay[camIndex] = 0;
			CameraSetupData.ShutterSpeed[camIndex] = 20;
			CameraSetupData.TriggerFreq[camIndex] = StudySetupData_SPB.TriggerFreq[camIndex];
			CameraSetupData.SubsamplingMode[camIndex] = 0;
		}
	}	
	CameraSetupData.TabletType = StudySetupData_SPB.TabletType;
	CameraSetupData.SensorLength = StudySetupData_SPB.SensorLength;
	CaptureFrameCount = CameraSetupData.FrameBufferCount;
	CaptureSetup(CameraSetupData.ShutterSpeed, CameraSetupData.TriggerFreq, CameraSetupData.SubsamplingMode, 0);
	ResetIntCapture();
}

void TabletCapture_InspectionMode()
{
	int camIndex;
	unsigned char *imageBuffer;
	TSPBTabletUnit *tabletUnit;
	SPBTabletProcessInfo.CaptureMode = MACHINE_CAPTURE_MODE_PROCESSING;
	SPBTabletProcessInfo.ProcessingMode = TABLET_PROCESSING_MODE_INSPECTION;

	ClearCaptureProcessingData();
	for (camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; camIndex++)
	{
		if (InspectData_SPB.CamMask& (0x0001 << camIndex))
		{
			CameraSetupData.CameraEnable[camIndex] = 1;
			CameraSetupData.ShutterDelay[camIndex] = InspectData_SPB.ShutterDelay[camIndex];
			CameraSetupData.ShutterSpeed[camIndex] = InspectData_SPB.ShutterSpeed[camIndex];
			CameraSetupData.TriggerFreq[camIndex] = InspectData_SPB.TriggerFreq[camIndex];
			CameraSetupData.SubsamplingMode[camIndex] = InspectData_SPB.SubSamplingMode[camIndex];
			SetImageControlMode(camIndex, IMAGE_CONTROL_MODE_PROCESSING);
			if(camIndex == 0)
				imageBuffer = ImageBuffer1;
			else if(camIndex == 1)
				imageBuffer = ImageBuffer2;
			else if(camIndex == 2)
				imageBuffer = ImageBuffer3;
			else if(camIndex == 3)
				imageBuffer = ImageBuffer4;

			SelectedImageControl_ClearBuffer(imageBuffer);						
		}
		else
		{
			CameraSetupData.CameraEnable[camIndex] = 0;
			CameraSetupData.ShutterDelay[camIndex] = 0;
			CameraSetupData.ShutterSpeed[camIndex] = 20;
			CameraSetupData.TriggerFreq[camIndex] = InspectData_SPB.TriggerFreq[camIndex];
			CameraSetupData.SubsamplingMode[camIndex] = 0;
		}
	}	
	CameraSetupData.TabletType = InspectData_SPB.TabletType;
	CameraSetupData.SensorLength = InspectData_SPB.SensorLength;
	CaptureFrameCount = CameraSetupData.FrameBufferCount;
	CaptureSetup(CameraSetupData.ShutterSpeed, CameraSetupData.TriggerFreq, CameraSetupData.SubsamplingMode, 0);
	SPBTabletProcessInfo.ExpectedNextTabletNumber[0] = InspectData_SPB.TotalTabletCount+1;
	SPBTabletProcessInfo.ExpectedNextTabletNumber[1] = InspectData_SPB.TotalTabletCount+1;
	err1_cnt = 0;
	ResetIntCapture();
}

void EnabledThreeDCameraSensor(int camIndex, int LSFValue, int calibrationMode)
{
	unsigned char *imageBuffer;
	TSPBTabletUnit *tabletUnit;

	ClearCaptureProcessingData();	

	Sensor_3d_Status = SENSOR_3D_STATUS_OFF;
	check_3d_image = 0; 

	if(SPBTabletProcessInfo.ProcessingMode == TABLET_PROCESSING_MODE_CALIBRATION || calibrationMode)
	{
		ImageControl_CalibMode_Clear();

		if(camIndex == 0)
			imageBuffer = ImageBuffer1;
		else if(camIndex == 1)
			imageBuffer = ImageBuffer2;
		else if(camIndex == 2)
			imageBuffer = ImageBuffer3;
		else if(camIndex == 3)
			imageBuffer = ImageBuffer4;

		SelectedImageControl_ClearBuffer(imageBuffer);
	}

	Set_3D_LineScanTime(LSFValue, camIndex);
	CHANGE_2D3D_REG = (0x01 << camIndex);

	NFACaptureInfo[camIndex].CaptureKind = CAPTURE_KIND_LINE;
	NFACaptureInfo[camIndex].Camera_kind = CAMERA_KIND_NFA_3D;
	NFACaptureInfo[camIndex].ShutterSpeed = 0;
	NFACaptureInfo[camIndex].LineScanTime = LSFValue;

	ThreeDBufferCheckSW = ThreeDBufferCheckSW2 = 0;

	NFA3D_Streaming_Control_Close(camIndex);
	NFA3D_Streaming_Control_Clear(camIndex);
	NFA3D_Streaming_Control_Open(camIndex);

	tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.NextCaptureListIndex]);
				
	if (SystemSetupData.CameraKind[camIndex] == CAMERA_KIND_NFA_3D)
	{		
		if(SPBTabletProcessInfo.ProcessingMode == TABLET_PROCESSING_MODE_CALIBRATION || calibrationMode)
		{
			if (CaptureFrameCount - ImageControl_CalibMode_GetFilledFrameCount(camIndex) < 2)
			{
				tabletUnit->CaptureImagePtr[camIndex] = ImageControl_CalibMode_GetLastFrameBuffer(camIndex);
				tabletUnit->CalibCaptureFrameIndex[camIndex] = ImageControl_CalibMode_GetLastFrameIndex(camIndex);
			}
			else
			{
				tabletUnit->CaptureImagePtr[camIndex] = ImageControl_CalibMode_GetLastFrameBuffer(camIndex);
				tabletUnit->CalibCaptureFrameIndex[camIndex] = ImageControl_CalibMode_GetLastFrameIndex(camIndex);			
				ImageControl_CalibMode_IncreaseFIFO(camIndex);
			}
		}
		else
		{
			tabletUnit->ImageFrameIndex = GetProcessingImageBufferIndex();	
			if (tabletUnit->ImageFrameIndex == -1)
			{
				tabletUnit->Result = SPB_TABLET_RESULT_UNINS_IMAGE_BUFFER_FULL;
				tabletUnit->State = SPB_TABLET_STATE_ERROR;				
			}
			else
			{
				tabletUnit->CaptureImagePtr[camIndex] = GetProcessingImageBufferPtr(camIndex, tabletUnit->ImageFrameIndex);	
			}				
		}
		
		if (NextCaptureTrigger(camIndex, tabletUnit->CaptureImagePtr[camIndex], &(tabletUnit->CaptureStatus[camIndex])) == 0)
		{
			if (SPBTabletProcessInfo.CaptureMode == MACHINE_CAPTURE_MODE_CAPTURE)
			{
				ImageControl_CalibMode_SetBufferState(camIndex, tabletUnit->CalibCaptureFrameIndex[camIndex], IC_CALIB_STATE_ON_CAPTURE);
			}
			tabletUnit->InspectionState[camIndex] = TABLET_INSPECTION_STATE_ON_CAPTURE;
		}
	}

	ResetIntCapture();
}


void TabletCapture_Stop(void)
{
	SPBTabletProcessInfo.CaptureMode = MACHINE_CAPTURE_MODE_NONE;
	SPBTabletProcessInfo.ProcessingMode = TABLET_PROCESSING_MODE_NONE;
	CameraSetupData.TabletType = UNCOATING;
	test_cam_count[9] = 1;
	ever_count= 0;
	if(0)//SystemSetupData.Laser_complexer_Enable==1)
	{	
		if(BoardID == BOARD_ID_SPB(7) || BoardID == BOARD_ID_SPB(8))
		{
			NFA_3D_SensorModeOff();
		}
	}
}

void OnReceiveTabletNumber(int sensor1TabletNumber, int sensor2TabletNumber, int sensor1TabletNumberValid, int sensor2TabletNumberValid)
{		
	if ((SPBTabletProcessInfo.TabletNumberRequestOn[0]) && sensor1TabletNumberValid)
	{
		SPBTabletProcessInfo.TabletNumberReceived[0] = 1;
		SPBTabletProcessInfo.ReceivedTabletNumber[0] = sensor1TabletNumber;
	}

	if ((SPBTabletProcessInfo.TabletNumberRequestOn[1]) && sensor2TabletNumberValid)
	{
		SPBTabletProcessInfo.TabletNumberReceived[1] = 1;
		SPBTabletProcessInfo.ReceivedTabletNumber[1] = sensor2TabletNumber;
	}    
}

void InitProcessingResultData(void)
{
	SPBProcessingResultData.CompleteCount = 0;
}


void MakeProcessingResultData(void)
{
	int listIndex, i, camIndex;
	TSPBTabletUnit *tabletUnit;
	TSPBProcessingResultData tempProcessingResultData;
	CSL_IntcEventEnableState ie;
	unsigned char proceedReportingIndex;

	listIndex = SPBTabletProcessInfo.ProcessingResultReportingListIndex;

	tempProcessingResultData.CompleteCount = 0;
	proceedReportingIndex = TRUE;
	for (i = 0; i < SPB_TABLET_LIST_COUNT; i++)
	{	
		tabletUnit = &(SPBTabletProcessInfo.TabletList[listIndex]);
		if (tabletUnit->State > SPB_TABLET_STATE_CAPTURED && tabletUnit->State <= SPB_TABLET_STATE_PROCESSING_COMPLETE)
		{
			tempProcessingResultData.ProcessedTabletNumber[tempProcessingResultData.CompleteCount] = tabletUnit->TabletNumber;
			tempProcessingResultData.ProcessingResult[tempProcessingResultData.CompleteCount] = tabletUnit->Result;
			tempProcessingResultData.DiskPosition[tempProcessingResultData.CompleteCount] = tabletUnit->SuctionDiscPos + 1;
			
			for (camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; camIndex++)
			{
				if (tabletUnit->InspectionState[camIndex] != TABLET_INSPECTION_STATE_PROCESSING_COMPLETE)		// prevent cheking unused camera
				{
					continue;
				}

				if (SystemSetupData.GlobalCameraIndex[camIndex] == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1 || 
					SystemSetupData.GlobalCameraIndex[camIndex] == SD2_3D_FRONT_FACE_CAMERA_INDEX - 1) // 3D
				{
					if (tabletUnit->ThickErrorSW[camIndex] == 1)
					{
						tempProcessingResultData.ProcessingResult[tempProcessingResultData.CompleteCount] |= SPB_TABLET_RESULT_THICKERROR_MASK; // THIN TABLET
					}
					else if (tabletUnit->ThickErrorSW[camIndex] == 2)
					{
						tempProcessingResultData.ProcessingResult[tempProcessingResultData.CompleteCount] |= SPB_TABLET_RESULT_FRONT_FACE_MASK; // FAT TABLET
					}
				}
				
				if (TabletCharacter_SPB.discriminationDisplay_kind == PRINT)
				{
					// 인쇄정은 2D 카메라 매칭 결과를 이용
					if (SystemSetupData.GlobalCameraIndex[camIndex] == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || 
						SystemSetupData.GlobalCameraIndex[camIndex] == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1) // 2D
					{
						// 인쇄 유무
						if (tabletUnit->PrintResult[camIndex] != 0)
						{
							tempProcessingResultData.ProcessingResult[tempProcessingResultData.CompleteCount] |= SPB_TABLET_RESULT_PRINT_IS_MASK;
						}
						
						// 인쇄 종류
						if(tabletUnit->PrintType[camIndex] == 0)
						{
							tempProcessingResultData.ProcessingResult[tempProcessingResultData.CompleteCount] &= 0x7F; // 8번째 bit를 0으로 세팅(첫번째 인쇄 유형)
						}
						else if(tabletUnit->PrintType[camIndex] == 1)
						{
							tempProcessingResultData.ProcessingResult[tempProcessingResultData.CompleteCount] |= SPB_TABLET_RESULT_PRINT_TYPE_MASK; // 8번째 bit를 1로 세팅(두번째 인쇄 유형)
						}	
//						ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_CPB_PROCESS_TIMEOUT, tabletUnit->TabletNumber,tabletUnit->PrintResult[camIndex],tabletUnit->SuctionDiscPos);
					}
				}
				else if (TabletCharacter_SPB.discriminationDisplay_kind == STAMP)
				{
					// 각인정은 3D 카메라 매칭 결과를 이용
					if (SystemSetupData.GlobalCameraIndex[camIndex] == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1 || 
						SystemSetupData.GlobalCameraIndex[camIndex] == SD2_3D_FRONT_FACE_CAMERA_INDEX - 1) // 3D
					{
						// 인쇄 유무
						if (tabletUnit->PrintResult[camIndex] != 0)
						{
							tempProcessingResultData.ProcessingResult[tempProcessingResultData.CompleteCount] |= SPB_TABLET_RESULT_PRINT_IS_MASK;
						}
						
						// 인쇄 종류
						if(tabletUnit->PrintType[camIndex] == 0)
						{
							tempProcessingResultData.ProcessingResult[tempProcessingResultData.CompleteCount] &= 0x7F; // 8번째 bit를 0으로 세팅(첫번째 인쇄 유형)
						}
						else if(tabletUnit->PrintType[camIndex] == 1)
						{
							tempProcessingResultData.ProcessingResult[tempProcessingResultData.CompleteCount] |= SPB_TABLET_RESULT_PRINT_TYPE_MASK; // 8번째 bit를 1로 세팅(두번째 인쇄 유형)
						}	
					}				
				}					
			}
			if (tabletUnit->State == SPB_TABLET_STATE_PROCESSING_COMPLETE)
			{
				if (proceedReportingIndex)
				{
					SPBTabletProcessInfo.ProcessingResultReportingListIndex = (SPBTabletProcessInfo.ProcessingResultReportingListIndex + 1) & SPB_TABLET_LIST_MASK;
				}
			}
			else
			{
				proceedReportingIndex = FALSE;
			}
			tempProcessingResultData.CompleteCount++;
			if (tempProcessingResultData.CompleteCount == SPB_PROCESSING_RESULT_COUNT) break;
		}
		else if (tabletUnit->State == SPB_TABLET_STATE_ERROR)
		{
			tempProcessingResultData.ProcessedTabletNumber[tempProcessingResultData.CompleteCount] = tabletUnit->TabletNumber;
			tempProcessingResultData.ProcessingResult[tempProcessingResultData.CompleteCount] = tabletUnit->Result;
			tempProcessingResultData.DiskPosition[tempProcessingResultData.CompleteCount] = tabletUnit->SuctionDiscPos + 1;
			tempProcessingResultData.CompleteCount++;
			if (proceedReportingIndex)
			{
				SPBTabletProcessInfo.ProcessingResultReportingListIndex = (SPBTabletProcessInfo.ProcessingResultReportingListIndex + 1) & SPB_TABLET_LIST_MASK;
			}
			if (tempProcessingResultData.CompleteCount == SPB_PROCESSING_RESULT_COUNT) break;
		}
		else if (tabletUnit->State == SPB_TABLET_STATE_NONE) break;
		listIndex = (listIndex + 1) & SPB_TABLET_LIST_MASK;
	} 
//	gie = IRQ_globalDisable();
	memcpy(&SPBProcessingResultData, &tempProcessingResultData, sizeof(TSPBProcessingResultData));
//	IRQ_globalRestore(gie);
}

void ProceedProcessingReport(void)
{
	int i;//, camIndex;
	TSPBTabletUnit *tabletUnit;
	//TSPBProcessingResultData tempProcessingResultData;
	//unsigned int gie;

	for (i = 0; i < SPB_TABLET_LIST_COUNT; i++)
	{	
		tabletUnit = &(SPBTabletProcessInfo.TabletList[SPBTabletProcessInfo.ProcessingResultReportingListIndex]);
		if (tabletUnit->State == SPB_TABLET_STATE_PROCESSING_COMPLETE || tabletUnit->State == SPB_TABLET_STATE_ERROR)
		{
			SPBTabletProcessInfo.ProcessingResultReportingListIndex = (SPBTabletProcessInfo.ProcessingResultReportingListIndex + 1) & SPB_TABLET_LIST_MASK;
		}
		else 
		{
			break;
		}
	} 
	MakeProcessingResultData();
}


void MakeStudyResultData(void)
{

}

void VirtualIntCapture(int EnabledSPB)
{	
	int i;
	int m;
	int captureListIndex;
	int camIndex;

	if(VirtualDataRenewalSW)
	{
		if(Board1MSTmr - VirtualTriggerTime > 2000) // 2초동안 검사를 하지 않으면 Renewal 전에 부여된 검사 대상이 모든 Process를 끝낸것으로 가정
		{
			VirtualDataRenewalSW = 0;
			
			memcpy(&CPBVirtualInspectionData, &CPBVirtualInspectionDataForRenewal, sizeof(TCPBVirtualInspectionData));
			for(m = 0; m < SYSTEM_SPB_CAMERA_COUNT; m++)
			{
				if(CPBVirtualInspectionData.CameraMask & (0x01 << m))
					CameraSetupData.CameraEnable[m] = 1;
				else
					CameraSetupData.CameraEnable[m] = 0;
			}
			
//			ClearCaptureProcessingData();	
		} 
		else
		{
			return;
		}
	}
		
	if (BoardID == BOARD_ID_SPB(1) || BoardID == BOARD_ID_SPB(2) || BoardID == BOARD_ID_SPB(3))
	{
		VirtualTabletNumberSensor1++;
		ProcessExternalCapture(SD1);
		OnReceiveTabletNumber(VirtualTabletNumberSensor1, VirtualTabletNumberSensor2, 1, 0);
	}
	else
	{
		VirtualTabletNumberSensor2++;
		ProcessExternalCapture(SD2);
		OnReceiveTabletNumber(VirtualTabletNumberSensor1, VirtualTabletNumberSensor2, 0, 1);
	}
	
	VirtualTriggerTime = Board1MSTmr;
}

void MakeTabletProcessingData()
{
	int i, camIndex;
	TSPBTabletUnit *tabletUnit;
	TSPBProcessingResultData tempProcessingResultData;
	char tabletSearch = 0;
	int m;
		

	for (i = 0; i < SPB_TABLET_LIST_COUNT; i++)
	{
		tabletUnit = &(SPBTabletProcessInfo.TabletList[i]);
		if(tabletUnit->TabletNumber > 0 && (Board50usTimer - tabletUnit->CaptureIntTime >= 8000))
		{
			VirtualSPBProcessedData[i].TabletNumber = tabletUnit->TabletNumber;
			//VirtualSPBProcessedData[i].ProcessStartTime = tabletUnit->CaptureIntTime * 20;
			for(m = 0; m < 4; m++)
			{
				VirtualSPBProcessedData[i].ProcessingResult[m] = tabletUnit->ProcessingResult[m];
				VirtualSPBProcessedData[i].CameraEnabled[m] = CameraSetupData.CameraEnable[m];
			
				if(VirtualSPBProcessedData[i].CameraEnabled[m])
				{
					VirtualSPBProcessedData[i].ImageSendTime[m] = ProcessingTimeList[i].ProcessingStartTime[m] - ProcessingTimeList[i].ImageSendStartTime[m];
					VirtualSPBProcessedData[i].CapturedTime[m] = ProcessingTimeList[i].CaptureEndTime[m] - ProcessingTimeList[i].CaptureStartTime[m];
					VirtualSPBProcessedData[i].CPBProcessingTime[m] = ProcessingTimeList[i].ProcessingEndTime[m] - ProcessingTimeList[i].ProcessingStartTime[m];
				}
				else
				{
					VirtualSPBProcessedData[i].ImageSendTime[m] = 0;
					VirtualSPBProcessedData[i].CapturedTime[m] = 0;
					VirtualSPBProcessedData[i].CPBProcessingTime[m] = 0;
				}
			}	
			
			VirtualSPBProcessedData[i].State = tabletUnit->State;
			VirtualSPBProcessedData[i].Result = tabletUnit->Result;
								
			VirtualSPBProcessedData[i].TabletAssignSW = 1;
			VirtualSPBProcessedData[i].ProcessingDataSetSW = 1;

			tabletUnit->TabletNumber = 0;
			memset(&ProcessingTimeList[i], 0, sizeof(TProcessingTime));

			break;		
		}
	
	}

	/*
	for (i = 0; i < SPB_TABLET_LIST_COUNT; i++)
	{	
		if(VirtualSPBProcessedData[i].TabletAssignSW && !VirtualSPBProcessedData[i].ProcessingDataSetSW)
		{
			if(Board1MSTmr - VirtualSPBProcessedData[i].ProcessStartTime > 50) //  프로세싱시간을 최대 500ms로 가정
			{
				for(j = 0; j < SPB_TABLET_LIST_COUNT; j++)
				{
					tabletUnit = &(SPBTabletProcessInfo.TabletList[j]);
					if(tabletUnit->TabletNumber == VirtualSPBProcessedData[i].TabletNumber && 
						tabletUnit->TabletNumber == ProcessingTimeList[j].TabletNumber)
					{
						tabletSearch = 1;

						//ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_PROCESS_RUNTIME, VirtualSPBProcessedData[i].TabletNumber
						//																	, ProcessingTimeList[j].TabletNumber
						//																	, tabletUnit->TabletNumber);

						for(m = 0; m < 4; m++)
						{
							VirtualSPBProcessedData[i].ProcessingResult[m] = tabletUnit->ProcessingResult[m];
							VirtualSPBProcessedData[i].CameraEnabled[m] = CameraSetupData.CameraEnable[m];
						
							if(VirtualSPBProcessedData[i].CameraEnabled[m])
							{
								VirtualSPBProcessedData[i].ImageSendTime[m] = ProcessingTimeList[j].ImageSendStartTime[0];
								VirtualSPBProcessedData[i].CapturedTime[m] = ProcessingTimeList[j].CaptureEndTime[m] - ProcessingTimeList[j].CaptureStartTime[m];
								VirtualSPBProcessedData[i].CPBProcessingTime[m] = ProcessingTimeList[j].ProcessingEndTime[m] - ProcessingTimeList[j].ProcessingStartTime[m];
							}
							else
							{
								VirtualSPBProcessedData[i].ImageSendTime[m] = 0;
								VirtualSPBProcessedData[i].CapturedTime[m] = 0;
								VirtualSPBProcessedData[i].CPBProcessingTime[m] = 0;
							}
						}	
						
						VirtualSPBProcessedData[i].State = tabletUnit->State;
						VirtualSPBProcessedData[i].Result = tabletUnit->Result;
											
						VirtualSPBProcessedData[i].ProcessingDataSetSW = 1;

						break;
					}
				}

				if(!tabletSearch)
				{
					VirtualSPBProcessedData[i].ProcessingDataSetSW = 0;				
				}
			}	
		}
	} 
	*/ 
}

void MakeLaserQueueData(int theta, int centerX, int centerY, int triggerTime)
{
	LaserPositionQueue.List[LaserPositionQueue.QueueEnd].TabletRotationTheta = theta;
	LaserPositionQueue.List[LaserPositionQueue.QueueEnd].TabletCenterX = centerX;
	LaserPositionQueue.List[LaserPositionQueue.QueueEnd].TabletCenterY = centerY;
	LaserPositionQueue.List[LaserPositionQueue.QueueEnd].TriggerTime = triggerTime;

	LaserPositionQueue.QueueEnd = (LaserPositionQueue.QueueEnd + 1) & LASER_QUEUE_MASK;
}

void SendLaserQueueData()
{
	int theta; 
	int centerX, centerY; 
	int triggerTime;
	TSPBTabletUnit *tabletUnit,*last_tabletUnit;
	tabletUnit = &(SPBTabletProcessInfo.TabletList[LaserPositionQueue.QueueStart]);
	last_tabletUnit = &(SPBTabletProcessInfo.TabletList[(LaserPositionQueue.QueueStart -1)& LASER_QUEUE_MASK]);
	if(LaserPositionQueue.QueueStart != LaserPositionQueue.QueueEnd)
	{
		theta = LaserPositionQueue.List[LaserPositionQueue.QueueStart].TabletRotationTheta;
		centerX = LaserPositionQueue.List[LaserPositionQueue.QueueStart].TabletCenterX;
		centerY = LaserPositionQueue.List[LaserPositionQueue.QueueStart].TabletCenterY;
		triggerTime = LaserPositionQueue.List[LaserPositionQueue.QueueStart].TriggerTime;

		if(Board50usTimer > triggerTime)
		{
//			ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_NONE, tabletUnit->TabletNumber,centerX,centerY);
//			ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_NONE, tabletUnit->TabletNumber,Board50usTimer-tabletUnit->CaptureIntTime,centerX);			
			LaserMcbsp_SendPacket(theta, centerX, centerY);
			LaserPositionQueue.QueueStart = (LaserPositionQueue.QueueStart + 1) & LASER_QUEUE_MASK;
		}
	}
}
