868 lines
40 KiB
Plaintext
868 lines
40 KiB
Plaintext
Compile function TOOL_PARMS_EVENTS(CtrlEntId, Event, @PARAMS)
|
|
! This form has been deprecated in favor of NDW_TOOL_PARMS_EVENTS
|
|
/***********************************************************************************************************************
|
|
|
|
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 : 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 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
|
|
|
|
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
|
|
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
|
|
Declare Function SRP_EditTable_Manager, Database_Services, Material_Services, Rds_Services, RGB, Obj_Recipe
|
|
|
|
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)
|
|
|
|
// Fill Recipe Combo Box
|
|
Query = 'SELECT RECIPE BY SEQ'
|
|
RList(Query, TARGET_SAVELIST$, 'RECIPE_LIST', 'Current List of Recipes', False$)
|
|
RecipeList = Database_Services('ReadDataRow', 'SYSLISTS', 'RECIPE_LIST')
|
|
// Remove field containing list description
|
|
RecipeList = Delete(RecipeList, 1, 0, 0)
|
|
Set_Property(@Window : '.COMBO_RECIPE', 'LIST', RecipeList)
|
|
|
|
Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', False$)
|
|
Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', False$)
|
|
|
|
GoSub Setup_OLE_Controls
|
|
|
|
SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, FormSize)
|
|
|
|
End Event
|
|
|
|
|
|
Event COMBO_REACTOR.CHANGED(NewData)
|
|
|
|
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
|
|
GoSub FillForm
|
|
Set_Property(CtrlEntId, 'MODIFIED', False$)
|
|
end
|
|
|
|
end event
|
|
|
|
|
|
Event COMBO_RECIPE.CHANGED(NewData)
|
|
|
|
GoSub FillRecipeInfo
|
|
// Clear the rest of the form until the user selects a PSN by which we can further,
|
|
// which is required to identify any TOOL_PARMS records.
|
|
Set_Property(@Window : '.COMBO_PSN', 'TEXT', '')
|
|
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', '')
|
|
|
|
end event
|
|
|
|
|
|
Event COMBO_PSN.CHANGED(NewData)
|
|
|
|
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', '')
|
|
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(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', Array)
|
|
Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', True$)
|
|
Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', True$)
|
|
end
|
|
|
|
end event
|
|
|
|
|
|
Event EDT_RECIPE_PARMS.CHANGED(NewData)
|
|
|
|
Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', True$)
|
|
Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', True$)
|
|
|
|
end event
|
|
|
|
|
|
Event EDT_RECIPE_PARMS.DELETEROW(RowNum, RowData)
|
|
|
|
Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', True$)
|
|
Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', True$)
|
|
|
|
end event
|
|
|
|
|
|
Event BTN_LOAD_CURR_RUN_PARMS.CLICK()
|
|
|
|
ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT')
|
|
If ReactorNo NE '' then
|
|
GoSub FillForm
|
|
Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', False$)
|
|
Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', False$)
|
|
end
|
|
|
|
end event
|
|
|
|
|
|
Event BTN_SET_CURR_RUN_PARMS.CLICK()
|
|
|
|
ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT')
|
|
PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT')
|
|
RecipeID = Get_Property(@Window : '.COMBO_RECIPE', 'TEXT')
|
|
|
|
If ReactorNo NE '' and PSN NE '' and RecipeID NE '' then
|
|
|
|
CurrentDTM = Date():'.':Time()
|
|
FormattedDTM = OConv(CurrentDTM, 'DT/^3H')
|
|
Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', FormattedDTM)
|
|
InternalDTMList = Get_Property(@Window, '@INTERNALDTMS', InternalDTMList)
|
|
ExternalDTMList = Get_Property(@Window, '@EXTERNALDTMS', ExternalDTMList)
|
|
InternalDTMList = Insert(InternalDTMList, 1, 0, 0, CurrentDTM)
|
|
ExternalDTMList = Insert(ExternalDTMList, 1, 0, 0, FormattedDTM)
|
|
Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', ExternalDTMList)
|
|
Set_Property(@Window, '@INTERNALDTMS', InternalDTMList)
|
|
Set_Property(@Window, '@EXTERNALDTMS', ExternalDTMList)
|
|
NewToolParmKey = RecipeID:'*':PSN:'*':ReactorNo:'*':CurrentDTM
|
|
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_DILUTENT', 'TEXT')
|
|
|
|
// 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$ ; // This field appears not be used at the moment
|
|
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$)
|
|
|
|
// Disable the Load and Set buttons so that the user knows these are the current run parameters
|
|
Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', False$)
|
|
Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', False$)
|
|
end
|
|
|
|
end event
|
|
|
|
|
|
Event COMBO_PARM_DTM.CHANGED(NewData)
|
|
|
|
GoSub FillRecipeParms
|
|
GoSub FormatEditTableColumns
|
|
Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', True$)
|
|
|
|
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 : '.COMBO_RECIPE', 'TEXT')
|
|
If RecipeID NE '' then
|
|
RecipeRec = Database_Services('ReadDataRow', 'RECIPE', RecipeID)
|
|
RecipeName = RecipeRec<RECIPE_RECIPE_NAME$>
|
|
RecipePSNs = RecipeRec<RECIPE_PROD_SPEC_IDS$>
|
|
RecipeDopant = RecipeRec<RECIPE_EPI_DOPANT$>
|
|
RecipeDiluent = RecipeRec<RECIPE_EPI_DILUENT$>
|
|
Set_Property(@Window : '.EDL_RECIPE_NAME', 'TEXT', RecipeName)
|
|
Set_Property(@Window : '.EDL_DOPANT', 'TEXT', RecipeDopant)
|
|
Set_Property(@Window : '.EDL_DILUENT', 'TEXT', RecipeDiluent)
|
|
Convert @VM to @FM in RecipePSNs
|
|
Set_Property(@Window : '.COMBO_PSN', 'LIST', RecipePSNs)
|
|
end
|
|
|
|
return
|
|
|
|
|
|
FillDatetimeInfo:
|
|
|
|
ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT')
|
|
PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT')
|
|
RecipeID = Get_Property(@Window : '.COMBO_RECIPE', 'TEXT')
|
|
|
|
If ReactorNo NE '' and PSN NE '' and RecipeID NE '' then
|
|
|
|
// Lookup associated TOOL_PARMS records
|
|
Query = 'SELECT TOOL_PARMS WITH REACTOR EQ ':ReactorNo:' AND WITH PSN EQ ':PSN:' AND WITH RECIPE EQ '
|
|
Query := RecipeID:' BY-DSND DATETIME'
|
|
GoSub ClearCursors
|
|
Set_Status(0)
|
|
RList(Query, TARGET_ACTIVELIST$, '', '' '')
|
|
ErrorCode = ''
|
|
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/^3H')
|
|
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 = RecipeID:'*':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)
|
|
GoSub CreateToolParmsRec
|
|
Msg(@Window, MsgUp)
|
|
ToolParmRec = NewToolParmRec
|
|
InternalDTMList = CurrentDTM
|
|
ExternalDTMList = FormattedDTM
|
|
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
|
|
|
|
|
|
CreateToolParmsRec:
|
|
|
|
ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT')
|
|
PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT')
|
|
RecipeID = Get_Property(@Window : '.COMBO_RECIPE', 'TEXT')
|
|
CurrentDTM = Date():'.':Time()
|
|
FormattedDTM = OConv(CurrentDTM, 'DT/^3H')
|
|
Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', FormattedDTM)
|
|
Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', FormattedDTM)
|
|
NewToolParmKey = RecipeID:'*':PSN:'*':ReactorNo:'*':CurrentDTM
|
|
NewToolParmRec = ''
|
|
|
|
Query = 'SELECT RDS WITH RECIPE_NO EQ ':RecipeID:' AND WITH PROD_SPEC_ID EQ ':PSN:' AND WITH REACTOR EQ '
|
|
Query := ReactorNo:' BY-DSND DATE_IN'
|
|
GoSub ClearCursors
|
|
Set_Status(0)
|
|
RList(Query, TARGET_ACTIVELIST$, '', '', '')
|
|
If Get_Status(ErrorCode) then
|
|
ErrorMsg = 'Error calling RList(): error code ':ErrorCode
|
|
Error_Services('Add', ErrorMsg)
|
|
return
|
|
end
|
|
NumResultRows = @RecCount
|
|
If NumResultRows GT 0 then
|
|
Readnext RDSKey then
|
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKey)
|
|
RDSLayerKeys = RDSRec<RDS_RDS_LAYER_KEYS$>
|
|
For each RDSLayerKey in RDSLayerKeys using @VM setting vPos
|
|
|
|
RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey)
|
|
LayerID = RDSLayerKey[-1, 'B*']
|
|
NewToolParmRec<TOOL_PARMS.LS_ID$, vPos> = LayerID
|
|
NewToolParmRec<TOOL_PARMS.DOPANT$, vPos> = RDSLayerRec<RDS_LAYER_DOPANT$>
|
|
NewToolParmRec<TOOL_PARMS.EPI_DILUENT$, vPos> = RDSLayerRec<RDS_LAYER_EPI_DILUENT$>
|
|
NewToolParmRec<TOOL_PARMS.EPI_TIME$, vPos> = RDSLayerRec<RDS_LAYER_EPI_TIME$>
|
|
NewToolParmRec<TOOL_PARMS.DILUENT_ADJ_PARAM$, vPos> = RDSLayerRec<RDS_LAYER_DILUENT_ADJ_PARAM$>
|
|
NewToolParmRec<TOOL_PARMS.DOPANT_FLOW$, vPos> = RDSLayerRec<RDS_LAYER_DOPANT_FLOW$>
|
|
NewToolParmRec<TOOL_PARMS.HCL_FLOW$, vPos> = RDSLayerRec<RDS_LAYER_HCL_FLOW$>
|
|
NewToolParmRec<TOOL_PARMS.BAKE_TIME$, vPos> = RDSLayerRec<RDS_LAYER_BAKE_TIME$>
|
|
NewToolParmRec<TOOL_PARMS.EPI_H2_FLOW$, vPos> = RDSLayerRec<RDS_LAYER_EPI_H2_FLOW$>
|
|
NewToolParmRec<TOOL_PARMS.TCS_FLOW$, vPos> = RDSLayerRec<RDS_LAYER_TCS_FLOW$>
|
|
NewToolParmRec<TOOL_PARMS.DCS_FLOW$, vPos> = RDSLayerRec<RDS_LAYER_DCS_FLOW$>
|
|
NewToolParmRec<TOOL_PARMS.AUX1$, vPos> = RDSLayerRec<RDS_LAYER_AUX1$>
|
|
NewToolParmRec<TOOL_PARMS.AUX2$, vPos> = RDSLayerRec<RDS_LAYER_AUX2$>
|
|
NewToolParmRec<TOOL_PARMS.F_OFFSET$, vPos> = RDSLayerRec<RDS_LAYER_F_OFFSET$>
|
|
NewToolParmRec<TOOL_PARMS.S_OFFSET$, vPos> = RDSLayerRec<RDS_LAYER_S_OFFSET$>
|
|
NewToolParmRec<TOOL_PARMS.R_OFFSET$, vPos> = RDSLayerRec<RDS_LAYER_R_OFFSET$>
|
|
NewToolParmRec<TOOL_PARMS.ETCH1$, vPos> = RDSLayerRec<RDS_LAYER_ETCH1$>
|
|
NewToolParmRec<TOOL_PARMS.ETCH2$, vPos> = RDSLayerRec<RDS_LAYER_ETCH2$>
|
|
NewToolParmRec<TOOL_PARMS.ETCH3$, vPos> = RDSLayerRec<RDS_LAYER_ETCH3$>
|
|
NewToolParmRec<TOOL_PARMS.OVERGROW_REQ$, vPos> = RDSLayerRec<RDS_LAYER_OVERGROW_REQ$>
|
|
NewToolParmRec<TOOL_PARMS.ENTRY_USERNAME$, vPos> = @USER4
|
|
NewToolParmRec<TOOL_PARMS.SUSC_ETCH$, vPos> = RDSLayerRec<RDS_LAYER_SUSC_ETCH$>
|
|
NewToolParmRec<TOOL_PARMS.UNLOAD_TEMP$, vPos> = RDSLayerRec<RDS_LAYER_UL_TEMP$>
|
|
|
|
Next RDSLayerKey
|
|
GoSub ClearCursors
|
|
|
|
end
|
|
end else
|
|
// No RDS records found that match this criteria. Widen the query to search the most recent
|
|
// RDS that matches the Recipe ID and PSN, but to any reactor.
|
|
Query = 'SELECT RDS WITH RECIPE_NO EQ ':RecipeID:' AND WITH PROD_SPEC_ID EQ ':PSN:' BY-DSND DATE_IN'
|
|
GoSub ClearCursors
|
|
Set_Status(0)
|
|
RList(Query, TARGET_ACTIVELIST$, '', '', '')
|
|
If Get_Status(ErrorCode) then
|
|
ErrorMsg = 'Error calling RList(): error code ':ErrorCode
|
|
Error_Services('Add', ErrorMsg)
|
|
return
|
|
end
|
|
Readnext RDSKey then
|
|
RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKey)
|
|
RDSLayerKeys = RDSRec<RDS_RDS_LAYER_KEYS$>
|
|
For each RDSLayerKey in RDSLayerKeys using @VM setting vPos
|
|
|
|
RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey)
|
|
LayerID = RDSLayerKey[-1, 'B*']
|
|
NewToolParmRec<TOOL_PARMS.LS_ID$, vPos> = LayerID
|
|
NewToolParmRec<TOOL_PARMS.DOPANT$, vPos> = RDSLayerRec<RDS_LAYER_DOPANT$>
|
|
NewToolParmRec<TOOL_PARMS.EPI_DILUENT$, vPos> = RDSLayerRec<RDS_LAYER_EPI_DILUENT$>
|
|
NewToolParmRec<TOOL_PARMS.EPI_TIME$, vPos> = RDSLayerRec<RDS_LAYER_EPI_TIME$>
|
|
NewToolParmRec<TOOL_PARMS.DILUENT_ADJ_PARAM$, vPos> = RDSLayerRec<RDS_LAYER_DILUENT_ADJ_PARAM$>
|
|
NewToolParmRec<TOOL_PARMS.DOPANT_FLOW$, vPos> = RDSLayerRec<RDS_LAYER_DOPANT_FLOW$>
|
|
NewToolParmRec<TOOL_PARMS.HCL_FLOW$, vPos> = RDSLayerRec<RDS_LAYER_HCL_FLOW$>
|
|
NewToolParmRec<TOOL_PARMS.BAKE_TIME$, vPos> = RDSLayerRec<RDS_LAYER_BAKE_TIME$>
|
|
NewToolParmRec<TOOL_PARMS.EPI_H2_FLOW$, vPos> = RDSLayerRec<RDS_LAYER_EPI_H2_FLOW$>
|
|
NewToolParmRec<TOOL_PARMS.TCS_FLOW$, vPos> = RDSLayerRec<RDS_LAYER_TCS_FLOW$>
|
|
NewToolParmRec<TOOL_PARMS.DCS_FLOW$, vPos> = RDSLayerRec<RDS_LAYER_DCS_FLOW$>
|
|
NewToolParmRec<TOOL_PARMS.AUX1$, vPos> = RDSLayerRec<RDS_LAYER_AUX1$>
|
|
NewToolParmRec<TOOL_PARMS.AUX2$, vPos> = RDSLayerRec<RDS_LAYER_AUX2$>
|
|
NewToolParmRec<TOOL_PARMS.F_OFFSET$, vPos> = RDSLayerRec<RDS_LAYER_F_OFFSET$>
|
|
NewToolParmRec<TOOL_PARMS.S_OFFSET$, vPos> = RDSLayerRec<RDS_LAYER_S_OFFSET$>
|
|
NewToolParmRec<TOOL_PARMS.R_OFFSET$, vPos> = RDSLayerRec<RDS_LAYER_R_OFFSET$>
|
|
NewToolParmRec<TOOL_PARMS.ETCH1$, vPos> = RDSLayerRec<RDS_LAYER_ETCH1$>
|
|
NewToolParmRec<TOOL_PARMS.ETCH2$, vPos> = RDSLayerRec<RDS_LAYER_ETCH2$>
|
|
NewToolParmRec<TOOL_PARMS.ETCH3$, vPos> = RDSLayerRec<RDS_LAYER_ETCH3$>
|
|
NewToolParmRec<TOOL_PARMS.OVERGROW_REQ$, vPos> = RDSLayerRec<RDS_LAYER_OVERGROW_REQ$>
|
|
NewToolParmRec<TOOL_PARMS.ENTRY_USERNAME$, vPos> = @USER4
|
|
NewToolParmRec<TOOL_PARMS.SUSC_ETCH$, vPos> = RDSLayerRec<RDS_LAYER_SUSC_ETCH$>
|
|
NewToolParmRec<TOOL_PARMS.UNLOAD_TEMP$, vPos> = RDSLayerRec<RDS_LAYER_UL_TEMP$>
|
|
|
|
Next RDSLayerKey
|
|
GoSub ClearCursors
|
|
end
|
|
end
|
|
|
|
Database_Services('WriteDataRow', 'TOOL_PARMS', NewToolParmKey, NewToolParmRec)
|
|
If Error_Services('NoError') else
|
|
Error_Services('Add', 'Error writing TOOL_PARMS record: ':NewToolParmKey)
|
|
end
|
|
|
|
return
|
|
|
|
|
|
FillForm:
|
|
|
|
ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT')
|
|
MostRecentRDS = Xlate('REACT_STATE', ReactorNo, 'LAST_RDS_NO', 'X')
|
|
PSN = Xlate('RDS', MostRecentRDS, 'PROD_SPEC_ID', '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 : '.COMBO_RECIPE', 'TEXT', RecipeID)
|
|
|
|
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')
|
|
RecipeID = Get_Property(@Window : '.COMBO_RECIPE', '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 = RecipeID:'*':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 : '.COMBO_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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 '' and 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 )
|
|
|
|
return
|