open-insight/LSL2/STPROC/NDW_TOOL_PARMS_EVENTS.txt
Infineon\StieberD 7762b129af pre cutover push
2024-09-04 20:33:41 -07:00

785 lines
34 KiB
Plaintext

Compile function NDW_TOOL_PARMS_EVENTS(CtrlEntId, Event, @PARAMS)
/***********************************************************************************************************************
This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
permission from Infineon.
Name : NDW_TOOL_PARMS_EVENTS
Description : This function acts as a commuter module for all events related to this window.
Notes : Commuter Modules are automatically called from the Promoted_Events function which is called by the
application-specific promoted event handler. This makes it possible to add QuickEvents that need to
execute Basic+ logic without having use the Form Designer to make the association, although this is
limited to the events which are currently promoted.
If the form needs to call the commuter module directly then the QuickEvent parameters should be
formatted like this:
'@SELF','@EVENT',['@PARAM1','@PARAMx']
Parameters :
CtrlEntId [in] -- The fully qualified name of the control calling the promoted event
Event [in] -- The event being executed. See the Notes section regarding "PRE" events
Param1-15 [in] -- Additional event parameter holders
EventFlow [out] -- Set to 1 or 0 so the calling event knows whether or not to chain forward. See comments in
EVENT_SETUP insert
History : (Date, Initials, Notes)
08/31/18 djs Created initial commuter module.
09/11/18 djs Form and commuter module ready for UAT.
***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
#window NDW_TOOL_PARMS
$Insert RDS_EQUATES
$Insert LOGICAL
$Insert EVENT_SETUP
$Insert RLIST_EQUATES
$Insert RECIPE_EQUATES
$Insert RDS_LAYER_EQUATES
$Insert TOOL_PARMS_EQUATES
$Insert RECIPE_PARMS_EQU
$Insert DICT_EQUATES
$Insert MSG_EQUATES
$Insert SCHED_DET_EQUATES
$Insert WO_DAILY_SCHED_EQU
EQU HIDDEN$ TO 32
Equ COL.LAYER_ID To 1
Equ COL.DEPOSIT To 2
Equ COL.DILUENT To 3
Equ COL.DOPANT_FLOW To 4
Equ COL.HCL_FLOW To 5
Equ COL.BAKE_TIME To 6
Equ COL.H2_FLOW To 7
Equ COL.TCS_FLOW To 8
Equ COL.DCS_FLOW To 9
Equ COL.AUX_1_FLOW To 10
Equ COL.AUX_2_FLOW To 11
Equ COL.F_OFFSET To 12
Equ COL.S_OFFSET To 13
Equ COL.R_OFFSET To 14
Equ COL.SUSC_ETCH To 15
Equ COL.ETCH_1 To 16
Equ COL.ETCH_2 To 17
Equ COL.ETCH_3 To 18
Equ COL.UNLOAD_TEMP To 19
Declare Subroutine Set_Property, End_Dialog, Send_Event, Set_Status, obj_WO_Mat, Btree.Extract, Send_Message
Declare Subroutine ErrMsg, Set_Property, obj_AppWindow, Send_Event, obj_WO_Mat_QA, obj_Tables, Msg, Tool_Parms_Services
Declare Subroutine Start_Window, End_Window, Database_Services
Declare Subroutine SRP_EditTable_Manager, SRP_Show_Window, Rds_Services, Form_Services, Error_Services
Declare Function Get_Property, Get_Status, Dialog_Box, obj_WM_Out, set_WinMsgVal, Form_Services, Error_Services
Declare Function Msg, obj_WO_Mat, Send_Message, obj_Tables, Start_Window, End_Window, QA_Services, Tool_Parms_Services
Declare Function SRP_EditTable_Manager, Database_Services, Material_Services, Rds_Services, RGB, Obj_Recipe
Declare Function Schedule_Services, SRP_Sort_Array
ErrTitle = 'Error in NDW_QA_Met_Result_Events'
ErrorMsg = ''
Result = ''
SubclassInfo = Form_Services('FindSubclassControl')
Subclass = SubclassInfo<1>
// Update the arguments so that the OpenInsight OLE event will treate the ActiveX event as a native event handler.
If Event EQ 'OLE' then
Transfer Event to OIEvent
Transfer Param1 to Event
Transfer Param2 to Param1
Transfer Param3 to Param2
* Transfer Param4 to Param3
* Transfer Param5 to Param4
* Transfer Param6 to Param5
* Transfer Param7 to Param6
* Transfer Param8 to Param7
end
GoToEvent Event for CtrlEntId else
// Event not implemented
end
Return EventFlow else EVENT_CONTINUE$
//-----------------------------------------------------------------------------
// EVENT HANDLERS
//-----------------------------------------------------------------------------
Event WINDOW.CREATE(CreateParam)
// Fill Reactor Combo Box
Query = 'SELECT REACTOR WITH REACT_NO GT 0 AND WITH REACT_NO LT 100 BY REACT_NO'
RList(Query, TARGET_SAVELIST$, 'REACTOR_LIST', 'Current List of Reactors', False$)
ReactorList = Database_Services('ReadDataRow', 'SYSLISTS', 'REACTOR_LIST')
// Remove field containing list description
ReactorList = Delete(ReactorList, 1, 0, 0)
Set_Property(@Window : '.COMBO_REACTOR', 'LIST', ReactorList)
Set_Property(@Window, '@PARMS_CHANGED', False$)
GoSub Setup_OLE_Controls
SRP_Show_Window(@Window, 'SYSTEM', 'C', 'C', 1, '', False$, False$, FormSize)
End Event
Event COMBO_REACTOR.CHANGED(NewData)
Set_Property(@Window : '.COMBO_PSN', 'ENABLED', True$)
Set_Property(@Window : '.COMBO_PARM_DTM', 'ENABLED', True$)
Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ENABLED', True$)
GoSub FillForm
Set_Property(CtrlEntId, 'MODIFIED', False$)
end event
Event COMBO_REACTOR.CHAR(VirtCode, ScanCode, CtrlKey, ShiftKey, AltKey)
Set_Property(CtrlEntId, 'MODIFIED', True$)
end event
Event COMBO_REACTOR.LOSTFOCUS(Flag, FocusID)
ModifiedFlag = Get_Property(CtrlEntID, 'MODIFIED')
If ModifiedFlag EQ True$ then
Set_Property(@Window : '.COMBO_PSN', 'ENABLED', True$)
Set_Property(@Window : '.COMBO_PARM_DTM', 'ENABLED', True$)
Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ENABLED', True$)
GoSub FillForm
Set_Property(CtrlEntId, 'MODIFIED', False$)
end
end event
Event COMBO_PSN.CHANGED(NewData)
NewPSN = NewData
NewRecipeID = Xlate('PROD_SPEC', NewPSN, 'RECIPE_NO', 'X')
Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', '')
Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', '')
Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', '')
Set_Property(@Window : '.EDT_RECIPE_LIMITS', 'ARRAY', '')
Set_Property(@Window : '.EDL_RECIPE_NAME', 'TEXT', '')
Set_Property(@Window : '.EDL_DOPANT', 'TEXT', '')
Set_Property(@Window : '.EDL_DILUENT', 'TEXT', '')
Set_Property(@Window : '.EDL_RECIPE', 'TEXT', NewRecipeID)
GoSub FillRecipeInfo
GoSub FillDatetimeInfo
GoSub FillRecipeParms
GoSub FillRecipeLimits
GoSub FormatEditTableColumns
end event
Event EDT_RECIPE_PARMS.INSERTROW(RowNum)
Array = Get_Property(CtrlEntID, 'ARRAY')
Layers = Array<COL.LAYER_ID>
NumRows = DCount(Layers, @VM)
Begin Case
Case NumRows EQ 0
LayerID = 'L1'
NewRowNum = 1
Case NumRows EQ 1
If Index(Layers, 'L1', 1) then
LayerID = 'L2'
NewRowNum = 2
end else
LayerID = 'L1'
NewRowNum = 1
end
Case NumRows EQ 2
Begin Case
Case Index(Layers, 'L1', 1) and Index(Layers, 'L2', 1)
LayerID = '2'
NewRowNum = 3
Case Index(Layers, 'L1', 1) and Index(Layers, '2', 1)
LayerID = 'L2'
NewRowNum = 2
Case Index(Layers, 'L2', 1) and Index(Layers, '2', 1)
LayerId = 'L1'
NewRowNum = 1
End Case
Case Otherwise$
LayerID = -1
End Case
If LayerID NE -1 then
Array = Insert(Array, COL.LAYER_ID, NewRowNum, 0, LayerID)
Set_Property(CtrlEntID, 'ARRAY', Array)
Set_Property(@Window, '@PARMS_CHANGED', True$)
end
end event
Event EDT_RECIPE_PARMS.CHANGED(NewData)
OrigArray = Get_Property(@Window, '@ORIGPARMSARRAY', RecipeParmsArray)
NewArray = Get_Property(CtrlEntID, 'ARRAY')
If OrigArray NE NewArray then
Set_Property(@Window, '@PARMS_CHANGED', True$)
end else
Set_Property(@Window, '@PARMS_CHANGED', False$)
end
end event
Event EDT_RECIPE_PARMS.DELETEROW(RowNum, RowData)
Set_Property(@Window, '@PARMS_CHANGED', True$)
end event
Event BTN_SET_CURR_RUN_PARMS.CLICK()
ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT')
PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT')
NewParms = Get_Property(@Window, '@PARMS_CHANGED')
If ReactorNo NE '' and PSN NE '' then
If NewParms EQ True$ then
CurrentTime = OConv(Time(), 'MT')
CurrentDate = OConv(Date(), 'D')
CurrentDTM = CurrentDate:' ':CurrentTime
InternalDTM = IConv(CurrentDTM, 'DT')
ExternalDTM = OConv(InternalDTM, 'DT/^3HS')
Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', ExternalDTM)
InternalDTMList = Get_Property(@Window, '@INTERNALDTMS', InternalDTMList)
ExternalDTMList = Get_Property(@Window, '@EXTERNALDTMS', ExternalDTMList)
InternalDTMList = Insert(InternalDTMList, 1, 0, 0, InternalDTM)
ExternalDTMList = Insert(ExternalDTMList, 1, 0, 0, ExternalDTM)
Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', ExternalDTMList)
Set_Property(@Window, '@INTERNALDTMS', InternalDTMList)
Set_Property(@Window, '@EXTERNALDTMS', ExternalDTMList)
NewToolParmKey = PSN:'*':ReactorNo:'*':InternalDTM
NewToolParmRec = ''
RecipeParmsArray = Get_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY')
LayerIDs = RecipeParmsArray<COL.LAYER_ID>
Dopant = Get_Property(@Window : '.EDL_DOPANT', 'TEXT')
EpiDiluent = Get_Property(@Window : '.EDL_DILUENT', 'TEXT')
EpiDiluent = IConv(EpiDiluent, 'MD2')
// Format Data to save parameters in internal format
ColNames = 'LS_ID':@FM:'EPI_TIME':@FM:'DILUENT_ADJ_PARAM':@FM:'DOPANT_FLOW':@FM:'HCL_FLOW':@FM
ColNames := 'BAKE_TIME':@FM:'EPI_H2_FLOW':@FM:'TCS_FLOW':@FM:'DCS_FLOW':@FM:'AUX1':@FM:'AUX2':@FM:'F_OFFSET'
ColNames := @FM:'S_OFFSET':@FM:'R_OFFSET':@FM:'SUSC_ETCH':@FM:'ETCH1':@FM:'ETCH2':@FM:'ETCH3':@FM:'UNLOAD_TEMP'
For each ColName in ColNames using @FM Setting Col
ParamData = RecipeParmsArray<Col>
Conversion = Xlate('DICT.TOOL_PARMS', ColName, DICT_CONV$, 'X')
If Conversion NE '' then
ParamData = IConv(ParamData, Conversion)
RecipeParmsArray<Col> = ParamData
end
next ColName
For each LayerID in LayerIDs using @VM setting vPos
NewToolParmRec<TOOL_PARMS.LS_ID$, vPos> = LayerID
NewToolParmRec<TOOL_PARMS.DOPANT$, vPos> = Dopant
NewToolParmRec<TOOL_PARMS.EPI_DILUENT$, vPos> = EpiDiluent
NewToolParmRec<TOOL_PARMS.EPI_TIME$, vPos> = RecipeParmsArray<COL.DEPOSIT>
NewToolParmRec<TOOL_PARMS.DILUENT_ADJ_PARAM$, vPos> = RecipeParmsArray<COL.DILUENT>
NewToolParmRec<TOOL_PARMS.DOPANT_FLOW$, vPos> = RecipeParmsArray<COL.DOPANT_FLOW>
NewToolParmRec<TOOL_PARMS.HCL_FLOW$, vPos> = RecipeParmsArray<COL.HCL_FLOW>
NewToolParmRec<TOOL_PARMS.BAKE_TIME$, vPos> = RecipeParmsArray<COL.BAKE_TIME>
NewToolParmRec<TOOL_PARMS.EPI_H2_FLOW$, vPos> = RecipeParmsArray<COL.H2_FLOW>
NewToolParmRec<TOOL_PARMS.TCS_FLOW$, vPos> = RecipeParmsArray<COL.TCS_FLOW>
NewToolParmRec<TOOL_PARMS.DCS_FLOW$, vPos> = RecipeParmsArray<COL.DCS_FLOW>
NewToolParmRec<TOOL_PARMS.AUX1$, vPos> = RecipeParmsArray<COL.AUX_1_FLOW>
NewToolParmRec<TOOL_PARMS.AUX2$, vPos> = RecipeParmsArray<COL.AUX_2_FLOW>
NewToolParmRec<TOOL_PARMS.F_OFFSET$, vPos> = RecipeParmsArray<COL.F_OFFSET>
NewToolParmRec<TOOL_PARMS.S_OFFSET$, vPos> = RecipeParmsArray<COL.S_OFFSET>
NewToolParmRec<TOOL_PARMS.R_OFFSET$, vPos> = RecipeParmsArray<COL.R_OFFSET>
NewToolParmRec<TOOL_PARMS.ETCH1$, vPos> = RecipeParmsArray<COL.ETCH_1>
NewToolParmRec<TOOL_PARMS.ETCH2$, vPos> = RecipeParmsArray<COL.ETCH_2>
NewToolParmRec<TOOL_PARMS.ETCH3$, vPos> = RecipeParmsArray<COL.ETCH_3>
NewToolParmRec<TOOL_PARMS.OVERGROW_REQ$, vPos> = False$
NewToolParmRec<TOOL_PARMS.ENTRY_USERNAME$, vPos> = @USER4
NewToolParmRec<TOOL_PARMS.SUSC_ETCH$, vPos> = RecipeParmsArray<COL.SUSC_ETCH>
NewToolParmRec<TOOL_PARMS.UNLOAD_TEMP$, vPos> = RecipeParmsArray<COL.UNLOAD_TEMP>
Next LayerID
Database_Services('WriteDataRow', 'TOOL_PARMS', NewToolParmKey, NewToolParmRec, True$)
end
Tool_Parms_Services('ApplyCurrentRunParms', PSN, ReactorNo)
If Error_Services('NoError') then
Msg(@Window, '', 'SUCCESS', '', 'Run parameters have been set for reactor ':ReactorNo)
end else
Errmsg('Error setting run parameters. Error message: ':Error_Services('GetMessage'))
end
end
end event
Event COMBO_PARM_DTM.CHANGED(NewData)
GoSub FillRecipeParms
GoSub FormatEditTableColumns
end event
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Setup_OLE_Controls:
Qualify = ''
Qualify<1> = 1
Qualify<4> = 0
return
ClearCursors:
For counter = 0 to 8
ClearSelect counter
Next counter
return
FillRecipeInfo:
RecipeID = Get_Property(@Window : '.EDL_RECIPE', 'TEXT')
If RecipeID NE '' then
RecipeRec = Database_Services('ReadDataRow', 'RECIPE', RecipeID)
RecipeName = RecipeRec<RECIPE_RECIPE_NAME$>
RecipeDopant = RecipeRec<RECIPE_EPI_DOPANT$>
RecipeDiluent = OConv(RecipeRec<RECIPE_EPI_DILUENT$>, 'MD2')
Set_Property(@Window : '.EDL_RECIPE_NAME', 'TEXT', RecipeName)
Set_Property(@Window : '.EDL_DOPANT', 'TEXT', RecipeDopant)
Set_Property(@Window : '.EDL_DILUENT', 'TEXT', RecipeDiluent)
end
return
FillDatetimeInfo:
ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT')
PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT')
InternalDTMList = ''
ExternalDTMList = ''
Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', '')
Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', '')
Set_Property(@Window, '@INTERNALDTMS', '')
Set_Property(@Window, '@EXTERNALDTMS', '')
If ReactorNo NE '' and PSN NE '' then
// Lookup associated TOOL_PARMS records
Query = 'SELECT TOOL_PARMS WITH REACTOR EQ ':ReactorNo:' AND WITH PSN EQ ':PSN:' BY-DSND DATETIME'
GoSub ClearCursors
Set_Status(0)
ErrorCode = ''
RList(Query, TARGET_ACTIVELIST$, '', '' '')
If Get_Status(ErrorCode) then
ErrorMsg = 'Error calling RList(): error code ':ErrorCode
Error_Services('Add', ErrorMsg)
return
end
Done = False$
InternalDTMList = ''
ExternalDTMList = ''
Loop
Readnext ToolParmKey Else Done = True$
Until Done
ThisDTM = ToolParmKey[-1, 'B*']
InternalDTMList<-1> = ThisDTM
ExternalDTMList<-1> = OConv(ThisDTM,'DT/^3HS')
Repeat
If ExternalDTMList NE '' then
// TOOL_PARM records found -> Populate form with the latest configuration.
Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', ExternalDTMList)
MostRecentInternalDTM = InternalDTMList<1>
MostRecentExternalDTM = ExternalDTMList<1>
Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', MostRecentExternalDTM)
// Read most recent Tool Parameter record
ToolParmKey = PSN:'*':ReactorNo:'*':MostRecentInternalDTM
ToolParmRec = Database_Services('ReadDataRow', 'TOOL_PARMS', ToolParmKey)
end else
// Datetime query returned zero records, therefore there are no configuration records for this
// reactor, recipe, and PSN combination. Query RDS table for the most recent RDS that matches this
// criteria to reference as the last known configuration. Then create and save the configuration
// record to the TOOL_PARMS database table.
MsgDef = ''
MsgDef<MTEXT$> = 'Building tool parameter record.' :@SVM: 'Please wait...'
MsgDef<MTYPE$> = 'U'
MsgDef<MJUST$> = 'C'
MsgUp = Msg(@Window, MsgDef)
NewToolParmKey = Tool_Parms_Services('CreateToolParmsRec', PSN, ReactorNo)
Msg(@Window, MsgUp)
NewToolParmDTM = Field(NewToolParmKey, '*', 3)
ExternalDTM = OConv(NewToolParmDTM, 'DT/^3HS')
InternalDTMList = NewToolParmDTM
ExternalDTMList = ExternalDTM
Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', ExternalDTM)
Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', ExternalDTM)
end
// Save internal and external Datetime lists for use elsewhere. This is necessary to correctly
// identify records due to floating point rounding errors associated with Datetime types.
Set_Property(@Window, '@INTERNALDTMS', InternalDTMList)
Set_Property(@Window, '@EXTERNALDTMS', ExternalDTMList)
end
return
FillPSNInfo:
StartDate = Date() - 30
SelReactor = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT')
WorkOrderList = ''
PSNList = ''
SchedDetKeys = Schedule_Services('GetScheduleDetailKeys', StartDate, '', SelReactor, '', '')
For each SchedDetKey in SchedDetKeys
SchedDet = Schedule_Services('GetScheduleDetail', SchedDetKey)
ThisWorkOrder = SchedDet<SCHED_DET_WO_NO$>
Locate ThisWorkOrder in WorkOrderList using @FM setting fPos else
WorkOrderList<-1> = ThisWorkOrder
ThisProdVer = Xlate('WO_LOG', ThisWorkOrder, 'PROD_VER_NO', 'X')
ThisPSN = Xlate('PROD_VER', ThisProdVer, 'PROC_STEP_PSN', 'X')
Locate ThisPSN in PSNList using @FM Setting pPos else
PSNList<-1> = ThisPSN
end
end
Next SchedDetKey
// Add most recent RDS' PSN in case it was not found in the schedule.
// This would occur if the user manually entered a PSN that is not on the schedule.
MostRecentPSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT')
Locate MostRecentPSN in PSNList using @FM setting pPos else
PSNList<-1> = MostRecentPSN
end
SortedPSNList = SRP_Sort_Array(PSNList, 'DR1', 1)
Set_Property(@Window : '.COMBO_PSN', 'LIST', SortedPSNList)
return
FillForm:
ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT')
DailySchedKey = 'WO_DAILY_SCHED':ReactorNo
DailySchedRec = Database_Services('ReadDataRow', 'CONFIG', DailySchedKey)
WorkOrderCust = DailySchedRec<WOCust$>
WorkOrderNo = FIELD(WorkOrderCust, ' ', 1)
PSN = Xlate('WO_LOG', WorkOrderNo, 'PS_NO', 'X')
PRSLayerKey = Xlate('PROD_SPEC', PSN, 'PRS_LAYER_KEY', 'X')
FirstLayerKey = PRSLayerKey<1,1>
RecipeID = Xlate('PRS_LAYER', FirstLayerKey, 'RECIPE_ID', 'X')
If ReactorNo NE '' and PSN NE '' and RecipeID NE '' then
// Fill most recent PSN, Recipe, and DateTime associated with the selected reactor
Set_Property(@Window : '.COMBO_PSN', 'TEXT', PSN)
Set_Property(@Window : '.EDL_RECIPE', 'TEXT', RecipeID)
GoSub FillPSNInfo
GoSub FillRecipeInfo
GoSub FillDatetimeInfo
GoSub FillRecipeParms
GoSub FillRecipeLimits
GoSub FormatEditTableColumns
end
return
FillRecipeParms:
ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT')
PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT')
ExternalDTM = Get_Property(@Window : '.COMBO_PARM_DTM', 'TEXT')
InternalDTMList = Get_Property(@Window, '@INTERNALDTMS')
ExternalDTMList = Get_Property(@Window, '@EXTERNALDTMS')
InternalDTM = ''
Locate ExternalDTM in ExternalDTMList using @FM setting fPos then
InternalDTM = InternalDTMList<fPos>
end
ToolParmKey = PSN:'*':ReactorNo:'*':InternalDTM
ToolParmRec = Database_Services('ReadDataRow', 'TOOL_PARMS', ToolParmKey)
If ToolParmRec NE '' then
RecipeParmsArray = ''
RecipeLayerKeys = ToolParmRec<TOOL_PARMS.LS_ID$>
For each LayerKey in RecipeLayerKeys using @VM setting vPos
RecipeParmsArray<COL.LAYER_ID , vPos> = LayerKey
RecipeParmsArray<COL.DEPOSIT , vPos> = ToolParmRec<TOOL_PARMS.EPI_TIME$, vPos>
RecipeParmsArray<COL.DILUENT , vPos> = ToolParmRec<TOOL_PARMS.DILUENT_ADJ_PARAM$, vPos>
RecipeParmsArray<COL.DOPANT_FLOW, vPos> = ToolParmRec<TOOL_PARMS.DOPANT_FLOW$, vPos>
RecipeParmsArray<COL.HCL_FLOW , vPos> = ToolParmRec<TOOL_PARMS.HCL_FLOW$, vPos>
RecipeParmsArray<COL.BAKE_TIME , vPos> = ToolParmRec<TOOL_PARMS.BAKE_TIME$, vPos>
RecipeParmsArray<COL.H2_FLOW , vPos> = ToolParmRec<TOOL_PARMS.EPI_H2_FLOW$, vPos>
RecipeParmsArray<COL.TCS_FLOW , vPos> = ToolParmRec<TOOL_PARMS.TCS_FLOW$, vPos>
RecipeParmsArray<COL.DCS_FLOW , vPos> = ToolParmRec<TOOL_PARMS.DCS_FLOW$, vPos>
RecipeParmsArray<COL.AUX_1_FLOW , vPos> = ToolParmRec<TOOL_PARMS.AUX1$, vPos>
RecipeParmsArray<COL.AUX_2_FLOW , vPos> = ToolParmRec<TOOL_PARMS.AUX2$, vPos>
RecipeParmsArray<COL.F_OFFSET , vPos> = ToolParmRec<TOOL_PARMS.F_OFFSET$, vPos>
RecipeParmsArray<COL.S_OFFSET , vPos> = ToolParmRec<TOOL_PARMS.S_OFFSET$, vPos>
RecipeParmsArray<COL.R_OFFSET , vPos> = ToolParmRec<TOOL_PARMS.R_OFFSET$, vPos>
RecipeParmsArray<COL.SUSC_ETCH , vPos> = ToolParmRec<TOOL_PARMS.SUSC_ETCH$, vPos>
RecipeParmsArray<COL.ETCH_1 , vPos> = ToolParmRec<TOOL_PARMS.ETCH1$, vPos>
RecipeParmsArray<COL.ETCH_2 , vPos> = ToolParmRec<TOOL_PARMS.ETCH2$, vPos>
RecipeParmsArray<COL.ETCH_3 , vPos> = ToolParmRec<TOOL_PARMS.ETCH3$, vPos>
RecipeParmsArray<COL.UNLOAD_TEMP, vPos> = ToolParmRec<TOOL_PARMS.UNLOAD_TEMP$, vPos>
Next LayerKey
Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', RecipeParmsArray)
end
return
FillRecipeLimits:
PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT')
RecipeID = Get_Property(@Window : '.EDL_RECIPE', 'TEXT')
RecipeRec = Database_Services('ReadDataRow', 'RECIPE', RecipeID)
RecipeParms = Get_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY')
LayerIDs = ''
If RecipeParms NE '' then
LayerIDs = RecipeParms<COL.LAYER_ID>
end else
// New Tool Parms record -> fetch recipe layer ids
PRSLayerNos = Xlate('PROD_SPEC', PSN, 'LAYER_NO', 'X')
For each LayerNo in PRSLayerNos using @VM setting vPos
PRSLayerKey = PSN:'*':LayerNo
LSID = Xlate('PRS_LAYER', PRSLayerKey, 'LS_ID', 'X')
LayerIDs<1,-1> = LSID
Next LayerNo
// Fill Recipe Parms edit table layer IDs for user
Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', LayerIDs)
end
LimitsArray = ''
For each LayerID in LayerIDs using @VM setting LayerIndex
RecipeLimits = Obj_Recipe('GetLimits', RecipeID:@RM:PSN:@RM:LayerID)
LimitsArray<COL.LAYER_ID , LayerIndex> = LayerID
If RecipeLimits<RP_DEPOSIT_TIME_MIN$> NE '' or RecipeLimits<RP_DEPOSIT_TIME_MAX$> NE '' then
Deposit = OCONV(RecipeLimits<RP_DEPOSIT_TIME_MIN$>:@SVM:RecipeLimits<RP_DEPOSIT_TIME_MAX$>,'MD1')
Swap @SVM with ' ~ ' in Deposit
end else
Deposit = ''
end
If RecipeLimits<RP_DILUENT_FLOW_MIN$> NE '' or RecipeLimits<RP_DILUENT_FLOW_MAX$> NE '' then
Diluent = OCONV(RecipeLimits<RP_DILUENT_FLOW_MIN$>:@SVM:RecipeLimits<RP_DILUENT_FLOW_MAX$>,'MD2')
Swap @SVM with ' ~ ' in Diluent
end else
Diluent = ''
end
If RecipeLimits<RP_DOPANT_FLOW_MAX$> NE '' or RecipeLimits<RP_DOPANT_FLOW_MAX$> NE '' then
DopantFlow = OCONV(RecipeLimits<RP_DOPANT_FLOW_MIN$>:@SVM:RecipeLimits<RP_DOPANT_FLOW_MAX$>,'MD2')
Swap @SVM with ' ~ ' in DopantFlow
end else
DopantFlow = ''
end
If RecipeLimits<RP_HCL_FLOW_MIN$> NE '' or RecipeLimits<RP_HCL_FLOW_MAX$> NE '' then
HCLFlow = OCONV(RecipeLimits<RP_HCL_FLOW_MIN$>:@SVM:RecipeLimits<RP_HCL_FLOW_MAX$>,'MD2')
Swap @SVM with ' ~ ' in HCLFlow
end else
HCLFlow = ''
end
If RecipeLimits<RP_BAKE_TIME_MIN$> NE '' or RecipeLimits<RP_BAKE_TIME_MAX$> NE '' then
BakeTime = OCONV(RecipeLimits<RP_BAKE_TIME_MIN$>:@SVM:RecipeLimits<RP_BAKE_TIME_MAX$>,'[SECONDS_CONV]')
Swap @SVM with ' ~ ' in BakeTime
end else
BakeTime = ''
end
If RecipeLimits<RP_H2_FLOW_MIN$> NE '' or RecipeLimits<RP_H2_FLOW_MAX$> NE '' then
H2Flow = OCONV(RecipeLimits<RP_H2_FLOW_MIN$>:@SVM:RecipeLimits<RP_H2_FLOW_MAX$>,'MD0')
Swap @SVM with ' ~ ' in H2Flow
end else
H2Flow = ''
end
If RecipeLimits<RP_TCS_FLOW_MIN$> NE '' or RecipeLimits<RP_TCS_FLOW_MAX$> NE '' then
TCSFlow = OCONV(RecipeLimits<RP_TCS_FLOW_MIN$>:@SVM:RecipeLimits<RP_TCS_FLOW_MAX$>,'MD1')
Swap @SVM with ' ~ ' in TCSFlow
end else
TCSFlow = ''
end
If RecipeLimits<RP_DCS_FLOW_MIN$> NE '' or RecipeLimits<RP_DCS_FLOW_MAX$> NE '' then
DCSFlow = OCONV(RecipeLimits<RP_DCS_FLOW_MIN$>:@SVM:RecipeLimits<RP_DCS_FLOW_MAX$>,'MD0')
Swap @SVM with ' ~ ' in DCSFlow
end else
DCSFlow = ''
end
If RecipeLimits<RP_AUX1_FLOW_MIN$> NE '' or RecipeLimits<RP_AUX1_FLOW_MAX$> NE '' then
AUX1Flow = OCONV(RecipeLimits<RP_AUX1_FLOW_MIN$>:@SVM:RecipeLimits<RP_AUX1_FLOW_MAX$>,'MD2')
Swap @SVM with ' ~ ' in AUX1Flow
end else
AUX1Flow = ''
end
If RecipeLimits<RP_AUX2_FLOW_MIN$> NE '' or RecipeLimits<RP_AUX2_FLOW_MAX$> NE '' then
AUX2Flow = OCONV(RecipeLimits<RP_AUX2_FLOW_MIN$>:@SVM:RecipeLimits<RP_AUX2_FLOW_MAX$>,'MD2')
Swap @SVM with ' ~ ' in AUX2Flow
end else
AUX2Flow = ''
end
If RecipeLimits<RP_FOFFSET_MIN$> NE '' or RecipeLimits<RP_FOFFSET_MAX$> NE '' then
FOffset = OCONV(RecipeLimits<RP_FOFFSET_MIN$>:@SVM:RecipeLimits<RP_FOFFSET_MAX$>,'MD0')
Swap @SVM with ' ~ ' in FOffset
end else
FOffset = ''
end
If RecipeLimits<RP_SOFFSET_MIN$> NE '' or RecipeLimits<RP_SOFFSET_MAX$> NE '' then
SOffset = OCONV(RecipeLimits<RP_SOFFSET_MIN$>:@SVM:RecipeLimits<RP_SOFFSET_MAX$>,'MD0')
Swap @SVM with ' ~ ' in SOffset
end else
SOffset = ''
end
If RecipeLimits<RP_ROFFSET_MIN$> NE '' or RecipeLimits<RP_ROFFSET_MAX$> NE '' then
ROffset = OCONV(RecipeLimits<RP_ROFFSET_MIN$>:@SVM:RecipeLimits<RP_ROFFSET_MAX$>,'MD0')
Swap @SVM with ' ~ ' in ROffset
end else
ROffset = ''
end
If RecipeLimits<RP_SUSC_ETCH_MIN$> NE '' or RecipeLimits<RP_SUSC_ETCH_MAX$> NE '' then
SuscEtch = OCONV(RecipeLimits<RP_SUSC_ETCH_MIN$>:@SVM:RecipeLimits<RP_SUSC_ETCH_MAX$>,'MD1')
Swap @SVM with ' ~ ' in SuscEtch
end else
SuscEtch = ''
end
If RecipeLimits<RP_ETCH1_MIN$> NE '' or RecipeLimits<RP_ETCH1_MAX$> NE '' then
Etch1 = OCONV(RecipeLimits<RP_ETCH1_MIN$>:@SVM:RecipeLimits<RP_ETCH1_MAX$>,'[SECONDS_CONV]')
Swap @SVM with ' ~ ' in Etch1
end else
Etch1 = ''
end
If RecipeLimits<RP_ETCH2_MIN$> NE '' or RecipeLimits<RP_ETCH2_MAX$> NE '' then
Etch2 = OCONV(RecipeLimits<RP_ETCH2_MIN$>:@SVM:RecipeLimits<RP_ETCH2_MAX$>,'[SECONDS_CONV]')
Swap @SVM with ' ~ ' in Etch2
end else
Etch2 = ''
end
If RecipeLimits<RP_ETCH3_MIN$> NE '' or RecipeLimits<RP_ETCH3_MAX$> NE '' then
Etch3 = OCONV(RecipeLimits<RP_ETCH3_MIN$>:@SVM:RecipeLimits<RP_ETCH3_MAX$>,'[SECONDS_CONV]')
Swap @SVM with ' ~ ' in Etch3
end else
Etch3 = ''
end
If RecipeLimits<RP_UL_TEMP_MIN$> NE '' or RecipeLimits<RP_UL_TEMP_MAX$> NE '' then
UnloadTemp = OCONV(RecipeLimits<RP_UL_TEMP_MIN$>:@SVM:RecipeLimits<RP_UL_TEMP_MAX$>,'MD0')
Swap @SVM with ' ~ ' in UnloadTemp
end else
UnloadTemp = ''
end
LimitsArray<COL.DEPOSIT , LayerIndex> = Deposit
LimitsArray<COL.DILUENT , LayerIndex> = Diluent
LimitsArray<COL.DOPANT_FLOW, LayerIndex> = DopantFlow
LimitsArray<COL.HCL_FLOW , LayerIndex> = HCLFlow
LimitsArray<COL.BAKE_TIME , LayerIndex> = BakeTime
LimitsArray<COL.H2_FLOW , LayerIndex> = H2Flow
LimitsArray<COL.TCS_FLOW , LayerIndex> = TCSFlow
LimitsArray<COL.DCS_FLOW , LayerIndex> = DCSFlow
LimitsArray<COL.AUX_1_FLOW , LayerIndex> = AUX1Flow
LimitsArray<COL.AUX_2_FLOW , LayerIndex> = AUX2Flow
LimitsArray<COL.F_OFFSET , LayerIndex> = FOffset
LimitsArray<COL.S_OFFSET , LayerIndex> = SOffset
LimitsArray<COL.R_OFFSET , LayerIndex> = ROffset
LimitsArray<COL.SUSC_ETCH , LayerIndex> = SuscEtch
LimitsArray<COL.ETCH_1 , LayerIndex> = Etch1
LimitsArray<COL.ETCH_2 , LayerIndex> = Etch2
LimitsArray<COL.ETCH_3 , LayerIndex> = Etch3
LimitsArray<COL.UNLOAD_TEMP, LayerIndex> = UnloadTemp
Next LayerID
Set_Property(@Window : '.EDT_RECIPE_LIMITS', 'ARRAY', LimitsArray)
return
FormatEditTableColumns:
RecipeParms = Get_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY')
RecipeLimits = Get_Property(@Window : '.EDT_RECIPE_LIMITS', 'ARRAY')
ParameterStyles = Send_Message(@Window : '.EDT_RECIPE_PARMS', 'COLSTYLE', 0, '')
LimitStyles = Send_Message(@Window : '.EDT_RECIPE_LIMITS', 'COLSTYLE', 0, '')
ColNames = 'LS_ID':@FM:'EPI_TIME':@FM:'DILUENT_ADJ_PARAM':@FM:'DOPANT_FLOW':@FM:'HCL_FLOW':@FM
ColNames := 'BAKE_TIME':@FM:'EPI_H2_FLOW':@FM:'TCS_FLOW':@FM:'DCS_FLOW':@FM:'AUX1':@FM:'AUX2':@FM:'F_OFFSET'
ColNames := @FM:'S_OFFSET':@FM:'R_OFFSET':@FM:'SUSC_ETCH':@FM:'ETCH1':@FM:'ETCH2':@FM:'ETCH3':@FM:'UNLOAD_TEMP'
For each ColName in ColNames using @FM Setting Col
RecipeLimitsColData = RecipeLimits<Col>
RecipeParmsColData = RecipeParms<Col>
Convert @VM to '' in RecipeLimitsColData
Convert @VM to '' in RecipeParmsColData
If RecipeLimitsColData = '' and RecipeParmsColData = '' then
ParameterStyles<Col> = BitOr( ParameterStyles<Col>, HIDDEN$ ) ;* Column not used -> Hide
LimitStyles<Col> = BitOr( LimitStyles<Col>, HIDDEN$ )
end else
ParameterStyles<Col> = BitAnd( ParameterStyles<Col>, BitNot(HIDDEN$) ) ;* Column used -> Show
LimitStyles<Col> = BitAnd( LimitStyles<Col>, BitNot(HIDDEN$) )
ParamData = RecipeParms<Col>
Conversion = Xlate('DICT.TOOL_PARMS', ColName, DICT_CONV$, 'X')
If Conversion NE '' then
ParamData = OConv(ParamData, Conversion)
RecipeParms<Col> = ParamData
end
end
next ColName
ParameterStyles = Send_Message(@WINDOW : '.EDT_RECIPE_PARMS', 'COLSTYLE', 0, ParameterStyles)
LimitStyles = Send_Message(@WINDOW : '.EDT_RECIPE_LIMITS', 'COLSTYLE', 0, LimitStyles)
Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', RecipeParms)
* Set_Property(@Window : '.EDT_RECIPE_PARMS', 'AUTOSIZECOL', 16 )
* Set_Property(@Window : '.EDT_RECIPE_LIMITS', 'AUTOSIZECOL', 16 )
Set_Property(@Window, '@ORIGPARMSARRAY', RecipeParms)
Set_Property(@Window : '.EDT_RECIPE_PARMS', 'MODIFIED', False$)
return