|
|
|
@ -3475,50 +3475,13 @@ void CCommonFlowMgr::CreatAnnealPrepareCmd(CWorkCmdInvoker &CmdInvoker,CWafer *
|
|
|
|
|
pCmd->BindingPar(pWafer);//绑定当前生产的wafer
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
//打开气帘
|
|
|
|
|
if(m_bAirCurtain)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_IO_Write);
|
|
|
|
|
pCmd->SetIntParVal(_IO_W_Anneal_AirCurtain);
|
|
|
|
|
pCmd->SetBoolParVal(bOPEN);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//设置后续动作的平台速度为空移速度
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdSetAsixSpeed *pCmd = new CWorkCmdSetAsixSpeed();
|
|
|
|
|
pCmd->SetAsixSpeedType(_AsixSpeedType_EmptyMoveXY);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
//测距仪测量焦距(m_bPJobFirstWafer决定当前wafer 是否需要调整焦距)
|
|
|
|
|
if(gDeviceStateMgr->QueryUsedFunc(_EUsedFunc_LaserDisMeter) && (pWafer->m_bNeedFoucsAdjust))
|
|
|
|
|
{
|
|
|
|
|
//发送eap 事件
|
|
|
|
|
{
|
|
|
|
|
CSecsEventInfo EventInfo;
|
|
|
|
|
EventInfo.m_EventType = _SecsEvent_Wafer_FoucsAdjust_Start;
|
|
|
|
|
EventInfo.m_Wafer = pWafer;
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_SendSecsEvent);
|
|
|
|
|
pCmd->SetSecsEventInfo(EventInfo);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
//创建自动校准的指令流程(完成后不回到焦距位置)(如果使用安全坐标,回到安全坐标)
|
|
|
|
|
CreatAutoFindFocusInvokerCmd(CmdInvoker,false);
|
|
|
|
|
//发送eap 事件
|
|
|
|
|
{
|
|
|
|
|
CSecsEventInfo EventInfo;
|
|
|
|
|
EventInfo.m_EventType = _SecsEvent_Wafer_FoucsAdjust_End;
|
|
|
|
|
EventInfo.m_Wafer = pWafer;
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_SendSecsEvent);
|
|
|
|
|
pCmd->SetSecsEventInfo(EventInfo);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//关闭气缸衰减器(现在XY 在测距仪位置)
|
|
|
|
|
}
|
|
|
|
|
//关闭气缸衰减器
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_IO_AirDimmerCtrl);
|
|
|
|
@ -3629,54 +3592,6 @@ void CCommonFlowMgr::CreatSubRecipeAnnealPrepareCmd(CWorkCmdInvoker &CmdInvoker
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_CheckWarningMsg);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
//自动控制N2
|
|
|
|
|
{
|
|
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_N2_STATE);
|
|
|
|
|
bool bN2Open = RecipePar.m_ParBoolVal;
|
|
|
|
|
if (!bN2Open)
|
|
|
|
|
{
|
|
|
|
|
//停止使用MFC检测
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_MFCUseSignal);
|
|
|
|
|
pCmd->SetIntParVal(0);
|
|
|
|
|
pCmd->SetBoolParVal(bCLOSE);
|
|
|
|
|
pCmd->CanNotCancel();
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_IO_Write);
|
|
|
|
|
pCmd->SetIntParVal(_IO_W_Anneal_N2);
|
|
|
|
|
pCmd->SetBoolParVal(bN2Open);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
if (bN2Open)
|
|
|
|
|
{
|
|
|
|
|
if (gAnnealMonitoringMgr->IsUseN2Flowmeter())
|
|
|
|
|
{
|
|
|
|
|
double CurVal = 0.0;
|
|
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_USE_CUR_N2VAL);
|
|
|
|
|
if (RecipePar.m_ParBoolVal)
|
|
|
|
|
{
|
|
|
|
|
CRecipeParameter RecipePar2 = Recipe.GetRecipePar(RECIPE_PAR_NAME_N2_VAL);
|
|
|
|
|
CurVal = RecipePar2.m_ParDoubleVal;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CurVal = gAnnealMonitoringMgr->GetCurMFCVal();
|
|
|
|
|
}
|
|
|
|
|
//设置N2流量
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_SetN2Val);
|
|
|
|
|
pCmd->SetDoubleParVal(CurVal);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//检查LDD 状态
|
|
|
|
|
if(gDeviceStateMgr->QueryUsedFunc(_EUsedFunc_LaserDeviceCtrl))
|
|
|
|
|
{
|
|
|
|
@ -3730,6 +3645,46 @@ void CCommonFlowMgr::CreatSubRecipeAnnealPrepareCmd(CWorkCmdInvoker &CmdInvoker
|
|
|
|
|
gLogMgr->WriteLogInfo(LogInfo);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
if (bCreatRecipeEdiCheckCmd)//创建cmd 不一定会执行
|
|
|
|
|
{
|
|
|
|
|
//Edi 复检开始工作(检查是否需要复检)
|
|
|
|
|
{
|
|
|
|
|
//功率密度复检参数是否发生变化
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_EdiCheckStart);
|
|
|
|
|
pCmd->SetBoolParVal(bRcpEdiParChange);
|
|
|
|
|
pCmd->SetBoolParVal2(pWafer->m_bNeedEdiCheck);//是否需要复检
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
//抓取光斑数据(Laser1和Laser2合并抓取一次)
|
|
|
|
|
//需要复检的时候才抓取光斑参数
|
|
|
|
|
if (!m_bIsManusal_Anneal_Test
|
|
|
|
|
&&gAnnealMonitoringMgr->IsbBeamCheckOnJobStart()
|
|
|
|
|
&& gDeviceStateMgr->QueryUsedFunc(_EUsedFunc_LaserBeamMeter))
|
|
|
|
|
{
|
|
|
|
|
//发送eap 事件
|
|
|
|
|
{
|
|
|
|
|
CSecsEventInfo EventInfo;
|
|
|
|
|
EventInfo.m_EventType = _SecsEvent_Beam_Check_Start;
|
|
|
|
|
EventInfo.m_Wafer = pWafer;
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_SendSecsEvent);
|
|
|
|
|
pCmd->SetSecsEventInfo(EventInfo);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
CreatLaserBeamFlowCmd(CmdInvoker, pWafer, true);
|
|
|
|
|
//发送eap 事件
|
|
|
|
|
{
|
|
|
|
|
CSecsEventInfo EventInfo;
|
|
|
|
|
EventInfo.m_EventType = _SecsEvent_Beam_Check_End;
|
|
|
|
|
EventInfo.m_Wafer = pWafer;
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_SendSecsEvent);
|
|
|
|
|
pCmd->SetSecsEventInfo(EventInfo);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//设置SubRecipe 的激光参数(频率电流和延时)
|
|
|
|
|
//Rcp 电流是0的时候也需要把电流设置为0
|
|
|
|
|
//参数不变的时候这个步骤不会消耗时间
|
|
|
|
@ -3887,89 +3842,6 @@ void CCommonFlowMgr::CreatSubRecipeAnnealPrepareCmd(CWorkCmdInvoker &CmdInvoker
|
|
|
|
|
//这个时候的激光参数已经设置为recipe 的参数
|
|
|
|
|
if(bCreatRecipeEdiCheckCmd)//创建cmd 不一定会执行
|
|
|
|
|
{
|
|
|
|
|
//Edi 复检开始工作(检查是否需要复检)
|
|
|
|
|
{
|
|
|
|
|
//功率密度复检参数是否发生变化
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_EdiCheckStart);
|
|
|
|
|
pCmd->SetBoolParVal(bRcpEdiParChange);
|
|
|
|
|
pCmd->SetBoolParVal2(pWafer->m_bNeedEdiCheck);//是否需要复检
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
//抓取光斑数据(Laser1和Laser2合并抓取一次)
|
|
|
|
|
//需要复检的时候才抓取光斑参数
|
|
|
|
|
if (!m_bIsManusal_Anneal_Test&&gAnnealMonitoringMgr->IsbBeamCheckOnJobStart() && gDeviceStateMgr->QueryUsedFunc(_EUsedFunc_LaserBeamMeter))
|
|
|
|
|
{
|
|
|
|
|
//发送eap 事件
|
|
|
|
|
{
|
|
|
|
|
CSecsEventInfo EventInfo;
|
|
|
|
|
EventInfo.m_EventType = _SecsEvent_Beam_Check_Start;
|
|
|
|
|
EventInfo.m_Wafer = pWafer;
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_SendSecsEvent);
|
|
|
|
|
pCmd->SetSecsEventInfo(EventInfo);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
CreatLaserBeamFlowCmd(CmdInvoker, pWafer, true);
|
|
|
|
|
//发送eap 事件
|
|
|
|
|
{
|
|
|
|
|
CSecsEventInfo EventInfo;
|
|
|
|
|
EventInfo.m_EventType = _SecsEvent_Beam_Check_End;
|
|
|
|
|
EventInfo.m_Wafer = pWafer;
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_SendSecsEvent);
|
|
|
|
|
pCmd->SetSecsEventInfo(EventInfo);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#if 0
|
|
|
|
|
//这里角度调整 _ExcuteAction_EdiCheckStart 后自适应,后面脉宽复检前等待自适应结束提升效率
|
|
|
|
|
if (gDeviceStateMgr->QueryUsedFunc(_EUsedFunc_TekOscilloscope))
|
|
|
|
|
{
|
|
|
|
|
CExcuteActionPar ActionPar;
|
|
|
|
|
ActionPar.m_ExcuteAction = _ExcuteAction_AdjustOsiiMaxAmplitude;
|
|
|
|
|
ActionPar.m_DoubleParVal = lfPluseWidth;//工艺时需要赋值需要的脉宽用于判断自适应成功
|
|
|
|
|
if (!bLaser2EdiZero && !bLaser1EdiZero)
|
|
|
|
|
{
|
|
|
|
|
ActionPar.m_DoubleParVal2 = 0;//工艺时需要赋值需要的脉宽用于判断自适应成功
|
|
|
|
|
}
|
|
|
|
|
else if (!bLaser1EdiZero)
|
|
|
|
|
{
|
|
|
|
|
ActionPar.m_DoubleParVal2 = lfLaser1PluseWidthOffset;//工艺时需要赋值需要的脉宽用于判断自适应成功
|
|
|
|
|
}
|
|
|
|
|
else if (!bLaser2EdiZero)
|
|
|
|
|
{
|
|
|
|
|
ActionPar.m_DoubleParVal2 = lfLaser2PluseWidthOffset;//工艺时需要赋值需要的脉宽用于判断自适应成功
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteActionPar(ActionPar);
|
|
|
|
|
pCmd->SetbEdiCheckCmd(true);//标记为edi check cmd
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
//把双光路复检LD转45度的cmd放到_ExcuteAction_EdiCheckStart 之后
|
|
|
|
|
//如果要进行edi check 并且使用两路激光的情况,先把衰减器2 的角度转到45
|
|
|
|
|
if((!bLaser2EdiZero && !bLaser1EdiZero)&&bCreatRecipeEdiCheckCmd)
|
|
|
|
|
{
|
|
|
|
|
double RotatoDimmer2Ang = POW_ZERO_DIMMER_ANG_45;
|
|
|
|
|
//log
|
|
|
|
|
{
|
|
|
|
|
Log.Format("->RotatoDimmer2Ang = %lf",RotatoDimmer2Ang);
|
|
|
|
|
LogInfo.m_LogMsg = Log;
|
|
|
|
|
gLogMgr->WriteLogInfo(LogInfo);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
CExcuteActionPar ActionPar;
|
|
|
|
|
ActionPar.m_ExcuteAction = _ExcuteAction_RotatoDimmer_ToAngle;
|
|
|
|
|
ActionPar.m_DoubleParVal = RotatoDimmer2Ang;
|
|
|
|
|
ActionPar.m_IntParVal = (int)_LaserDeviceType_MainLaser2;
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteActionPar(ActionPar);
|
|
|
|
|
pCmd->SetbEdiCheckCmd(true);//标记为edi check cmd 不复检的时候就不执行
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
//XY移动到功率计位置
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdAsixXYMove *pCmd = new CWorkCmdAsixXYMove();
|
|
|
|
@ -4214,6 +4086,32 @@ void CCommonFlowMgr::CreatSubRecipeAnnealPrepareCmd(CWorkCmdInvoker &CmdInvoker
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//测距仪测量焦距(m_bPJobFirstWafer决定当前wafer 是否需要调整焦距)
|
|
|
|
|
if (gDeviceStateMgr->QueryUsedFunc(_EUsedFunc_LaserDisMeter) && (pWafer->m_bNeedFoucsAdjust))
|
|
|
|
|
{
|
|
|
|
|
//发送eap 事件
|
|
|
|
|
{
|
|
|
|
|
CSecsEventInfo EventInfo;
|
|
|
|
|
EventInfo.m_EventType = _SecsEvent_Wafer_FoucsAdjust_Start;
|
|
|
|
|
EventInfo.m_Wafer = pWafer;
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_SendSecsEvent);
|
|
|
|
|
pCmd->SetSecsEventInfo(EventInfo);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
//创建自动校准的指令流程(完成后不回到焦距位置)(如果使用安全坐标,回到安全坐标)
|
|
|
|
|
CreatAutoFindFocusInvokerCmd(CmdInvoker, false);
|
|
|
|
|
//发送eap 事件
|
|
|
|
|
{
|
|
|
|
|
CSecsEventInfo EventInfo;
|
|
|
|
|
EventInfo.m_EventType = _SecsEvent_Wafer_FoucsAdjust_End;
|
|
|
|
|
EventInfo.m_Wafer = pWafer;
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_SendSecsEvent);
|
|
|
|
|
pCmd->SetSecsEventInfo(EventInfo);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//Z 轴到激光焦点位置(加上sub recipe 的焦距调整值)
|
|
|
|
|
//cmd执行时再去获取当前的激光焦距坐标
|
|
|
|
|
{
|
|
|
|
@ -4225,6 +4123,65 @@ void CCommonFlowMgr::CreatSubRecipeAnnealPrepareCmd(CWorkCmdInvoker &CmdInvoker
|
|
|
|
|
pCmd->SetbMoveToLaserFoucsZ(true,FoucsZAdjustVal);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
//打开气帘
|
|
|
|
|
if (m_bAirCurtain)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_IO_Write);
|
|
|
|
|
pCmd->SetIntParVal(_IO_W_Anneal_AirCurtain);
|
|
|
|
|
pCmd->SetBoolParVal(bOPEN);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//自动控制N2
|
|
|
|
|
{
|
|
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_N2_STATE);
|
|
|
|
|
bool bN2Open = RecipePar.m_ParBoolVal;
|
|
|
|
|
if (!bN2Open)
|
|
|
|
|
{
|
|
|
|
|
//停止使用MFC检测
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_MFCUseSignal);
|
|
|
|
|
pCmd->SetIntParVal(0);
|
|
|
|
|
pCmd->SetBoolParVal(bCLOSE);
|
|
|
|
|
pCmd->CanNotCancel();
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_IO_Write);
|
|
|
|
|
pCmd->SetIntParVal(_IO_W_Anneal_N2);
|
|
|
|
|
pCmd->SetBoolParVal(bN2Open);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
if (bN2Open)
|
|
|
|
|
{
|
|
|
|
|
if (gAnnealMonitoringMgr->IsUseN2Flowmeter())
|
|
|
|
|
{
|
|
|
|
|
double CurVal = 0.0;
|
|
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_USE_CUR_N2VAL);
|
|
|
|
|
if (RecipePar.m_ParBoolVal)
|
|
|
|
|
{
|
|
|
|
|
CRecipeParameter RecipePar2 = Recipe.GetRecipePar(RECIPE_PAR_NAME_N2_VAL);
|
|
|
|
|
CurVal = RecipePar2.m_ParDoubleVal;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CurVal = gAnnealMonitoringMgr->GetCurMFCVal();
|
|
|
|
|
}
|
|
|
|
|
//设置N2流量
|
|
|
|
|
{
|
|
|
|
|
CWorkCmdExcuteAction *pCmd = new CWorkCmdExcuteAction();
|
|
|
|
|
pCmd->SetExcuteAction(_ExcuteAction_SetN2Val);
|
|
|
|
|
pCmd->SetDoubleParVal(CurVal);
|
|
|
|
|
CmdInvoker.AddCmd(pCmd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//加工前立即检测一次光路功率
|
|
|
|
|
if (!m_bSubRecipeEdiEqualZero)
|
|
|
|
|
{
|
|
|
|
|