open-insight/LSL2/STPROC/PSN_SERVICES.txt
2024-12-02 13:53:17 -07:00

953 lines
46 KiB
Plaintext

Function PSN_Services(@Service, @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 SRP Computer Solutions, Inc.
Name : PSN_Services
Description : Handler program for all module related services.
Notes : Service module to support environmental state issues. Environmental refers to the state of the
operating system, which includes version, client vs. server, and path to critical systems.
Parameters :
Service [in] -- Name of the service being requested
Param1-10 [in/out] -- Additional request parameter holders
Response [out] -- Response to be sent back to the Controller (MCP) or requesting procedure
Metadata :
History : (Date, Initials, Notes)
11/30/20 djs Original programmer.
***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
$insert LOGICAL
$insert SERVICE_SETUP
$insert PROD_SPEC_EQUATES
$insert PRS_STAGE_EQUATES
$Insert WO_MAT_QA_EQUATES
$Insert QA_MET_EQUATES
$Insert RDS_TEST_EQUATES
$Insert RDS_TEST_PROP_EQUATES
$Insert PRS_LAYER_EQU
Declare function Database_Services, Psn_Services, obj_Prod_Spec, Error_Services, SRP_JSON, Cust_Epi_Part_Services
Declare function Prod_Ver_Services, PRS_Stage_Services
Declare subroutine Database_Services, Psn_Services, Error_Services, SRP_JSON
GoToService else
Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.')
end
Return Response OR ''
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Service Parameter Options
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Options BOOLEAN = True$, False$
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Services
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------------------------------------
// InitializeCritParams
//
//----------------------------------------------------------------------------------------------------------------------
Service InitializeCritParams(PSNo)
PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo)
PSRec<PROD_SPEC_CRITICAL_WARP_MAX$> = 100
PSRec<PROD_SPEC_CRITICAL_BOW_MIN$> = -40
PSRec<PROD_SPEC_CRITICAL_BOW_MAX$> = 50
Database_Services('WriteDataRow', 'PROD_SPEC', PSNo, PSRec, True$, False$, True$)
end service
Service CheckPSNStages(PSNo, Stage)
Begin Case
Case Stage Eq 'PRE'
CleansCheck = Psn_Services('CheckCleansParms', PSNo, Stage)
IF Error_Services('GetMessage') NE '' then
Return
end
VisualCheck = Psn_Services('CheckVisualParms', PSNo, Stage)
IF Error_Services('GetMessage') NE '' then
Return
end
Case Stage Eq 'LOAD'
InstructionsCheck = Psn_Services('CheckInstructionParms', PSNo, Stage)
IF Error_Services('GetMessage') NE '' then
Return
end
Case Stage Eq 'FWI'
VisualCheck = Psn_Services('CheckVisualParms', PSNo, Stage)
IF Error_Services('GetMessage') NE '' then
Return
end
Case Stage Eq 'LWI'
VisualCheck = Psn_Services('CheckVisualParms', PSNo, Stage)
IF Error_Services('GetMessage') NE '' then
Return
end
SurfaceCheck = Psn_Services('CheckSurfaceParms',PSNo, Stage)
IF Error_Services('GetMessage') NE '' then
Return
end
Case Stage Eq 'POST'
CleansCheck = Psn_Services('CheckCleansParms', PSNo, Stage)
IF Error_Services('GetMessage') NE '' then
Return
end
SurfaceCheck = Psn_Services('CheckSurfaceParms',PSNo, Stage)
IF Error_Services('GetMessage') NE '' then
Return
end
Case Stage Eq 'QA' OR 'UNLOAD'
QAMetCheck = Psn_Services('CheckQAMetParms', PSNo, Stage)
IF Error_Services('GetMessage') NE '' then
Return
end
End Case
GoSub CheckAdHoc
Return
end service
Service CheckCleansParms(PSNo, Stage)
Response = 1
StageRecKey = PSNo: '*' : Stage
StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X')
IF StageRec<PRS_STAGE_CLEAN_SIG_REQ$> EQ 1 then
IF StageRec<PRS_STAGE_CLEAN_TOOL$> EQ '' then
FailReason = 'Clean Tool not selected for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
If StageRec<PRS_STAGE_CLEAN_RECIPE$> EQ '' then
FailReason = 'Clean Recipe not selected for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
end else
IF Stage EQ 'PRE' OR Stage EQ 'POST' then
FailReason = 'Cleans Signature Required for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
end
return
end service
Service CheckVisualParms(PSNo, Stage)
Response = 1
StageRecKey = PSNo: '*' : Stage
StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X')
If StageRec<PRS_STAGE_INSP_SIG_REQ$> EQ 1 then
IF StageRec<PRS_STAGE_MICROSCOPE$> EQ 1 then
IF StageRec<PRS_STAGE_LPD$> EQ '' then
FailReason = 'Frontside LPD limits must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
//Front Side Scratch Count
IF StageRec<PRS_STAGE_SCRATCHES$> EQ '' then
FailReason = 'Frontside Scratch Count must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
//Front Side Scratch Length
IF StageRec<PRS_STAGE_SCRATCH_LEN$> EQ '' then
FailReason = 'Frontside Scratch Length must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
//Front Side Pits
IF StageRec<PRS_STAGE_PITS$> EQ '' then
FailReason = 'Frontside Pits count must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
//Front Side Mounds
IF StageRec<PRS_STAGE_MOUNDS$> EQ '' then
FailReason = 'Frontside Mounds count must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
//Front Side Spots
IF StageRec<PRS_STAGE_SPOTS$> EQ '' then
FailReason = 'Frontside Spots count must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
//Front Side FOV
IF StageRec<PRS_STAGE_FOV$> EQ '' then
Response = 'Frontside FOV must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
//Front Side BL Defects
IF StageRec<PRS_STAGE_BL_DEFECTS$> EQ '' then
FailReason = 'Frontside BL Defects must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
end else
IF Stage EQ 'PRE' OR Stage EQ 'FWI' OR Stage EQ 'LWI' then
FailReason = 'Microscope Inspection Required for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
end
IF StageRec<PRS_STAGE_BRIGHTLIGHT$> EQ 1 then
//Back Side Scratches
IF StageRec<PRS_STAGE_BSIDE_SCRATCHES$> EQ '' then
FailReason = 'Backside Scratch Count must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
//Back Side Scratch Length
IF StageRec<PRS_STAGE_BSIDE_SCRATCH_LEN$> EQ '' then
FailReason = 'Backside Scratch Length must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
end else
IF Stage EQ 'PRE' OR Stage EQ 'FWI' OR Stage EQ 'LWI' then
FailReason = 'Brightlight Inspection Required for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
end
end else
IF Stage EQ 'PRE' OR Stage EQ 'FWI' OR Stage EQ 'LWI' then
FailReason = 'Visual Inspection Signature Required for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
end
return
end service
Service CheckInstructionParms(PSNo, Stage)
Response = 1
StageRecKey = PSNo: '*' : Stage
StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X')
//Currently the only place where instruction would be required is the LOAD stage
IF Stage EQ 'LOAD' then
IF StageRec<PRS_STAGE_INST$> EQ '' then
FailReason = 'Instructions Missing for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
end
Return
end service
Service CheckSurfaceParms(PSNo, Stage)
FailReason = 1
StageRecKey = PSNo: '*' : Stage
StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X')
IF StageRec<PRS_STAGE_SURFSCAN_SIG_REQ$> EQ 1 then
SSRecipes = StageRec<PRS_STAGE_SURFSCAN_RECIPE$>
IF SSRecipes NE '' then
For RecipePos = 1 To DCOUNT(SSRecipes, @VM)
IF StageRec<PRS_STAGE_SURF_DEFECTS$, RecipePos> EQ '' then
FailReason = 'SurfScan Defect Count must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
//Surf Haze
IF StageRec<PRS_STAGE_SURF_HAZE$, RecipePos> EQ '' then
FailReason = 'SurfScan Haze must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
//Surf sample qty
IF StageRec<PRS_STAGE_SS_SAMP_QTY$, RecipePos> EQ '' then
FailReason = 'SurfScan Cassette Sample Size must be set for ':Stage:' stage.'
Error_Services('Add', FailReason)
return
end
Next RecipePos
end else
FailReason = 'No SurfScan Recipe has been set for ' : Stage : 'stage.'
Error_Services('Add', FailReason)
return
end
end else
IF Stage EQ 'POST' OR Stage EQ 'LWI' then
FailReason = 'SurfScan signature must be set to "Required" for ' : Stage : 'stage.'
Error_Services('Add', FailReason)
return
end
end
return
end service
Service CheckQAMetParms(PSNo, Stage)
FailReason = 1
StageRecKey = PSNo: '*' : Stage
StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X')
QAMetTests = StageRec<PRS_STAGE_MET_TEST$>
IF QAMetTests NE '' then
For MetTest = 1 to DCount(QAMetTests, @VM)
IF StageRec<PRS_STAGE_MET_TOOL_CLASS$,MetTest> EQ '' then
FailReason = 'QA Metrology Tool class must be set for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
IF StageRec<PRS_STAGE_MET_RECIPE$,MetTest> EQ '' then
FailReason = 'QA Metrology Tool Recipe must be set for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
IF StageRec<PRS_STAGE_MET_RECIPE_PATTERN$,MetTest> EQ '' then
FailReason = 'QA Metrology Tool Recipe Pattern must be set for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
IF StageRec<PRS_STAGE_MET_MIN$,MetTest> EQ '' then
FailReason = 'QA Metrology Minimum must be set for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
IF StageRec<PRS_STAGE_MET_MAX$,MetTest> EQ '' then
FailReason = 'QA Metrology Maximum must be set for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
IF StageRec<PRS_STAGE_MET_SLOT$,MetTest> EQ '' then
FailReason = 'QA Metrology slot must be set for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
IF StageRec<PRS_STAGE_MET_WFR_QTY$,MetTest> EQ '' then
FailReason = 'QA Metrology Wafer Quantity must be set for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
IF StageRec<PRS_STAGE_MET_INTERVAL$,MetTest> EQ '' then
FailReason = 'QA Metrology Wafer Interval must be set for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
IF StageRec<PRS_STAGE_MET_START$,MetTest> EQ '' then
FailReason = 'QA Metrology Start must be set for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
IF StageRec<PRS_STAGE_MET_PHASE_MIN$,MetTest> EQ '' AND StageRec<PRS_STAGE_MET_TEST$, MetTest> EQ 'CRES' then
FailReason = 'QA Metrology Phase min must be set for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
Next MetTest
end else
IF Stage EQ 'QA' OR Stage EQ 'UNLOAD' then
FailReason = 'No Metrology Tests exist for ' : Stage : ' stage.'
Error_Services('Add', FailReason)
return
end
end
return
end service
//----------------------------------------------------------------------------------------------------------------------
// UpdateQAMetrologyLimits
//
// Purpose: Update the specification limits for a particular QA metrology test.
//----------------------------------------------------------------------------------------------------------------------
Service UpdateQAMetrologyLimits(WOMatQAKey, QAMetStage, QAMetProfile, QAMetSlot)
TestFound = False$
ErrorMsg = ''
If ( (WOMatQAKey NE '') and (QAMetStage NE '') and (QAMetProfile NE '') and (QAMetSlot NE '') ) then
// Ensure QAMetProfile is prepended with a '1'.
If QAMetProfile[1, 1] NE 1 then QAMetProfile = 1:QAMetProfile
WOStepKey = Field(WOMatQAKey, '*', 1) : '*1'
PSNo = Xlate('WO_STEP', WOStepKey, 'PROD_SPEC_ID', 'X')
If PSNo NE '' then
PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo)
If Error_Services('NoError') then
// Retrieve new QA metrology data from PSN.
SpecQAMetData = obj_Prod_Spec('GetQAMet',PSNo:@RM:PSRec)
If SpecQAMetData NE '' then
WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey)
If Error_Services('NoError') then
RecQAMetStages = WOMatQARec<WO_MAT_QA_STAGE$>
RecQAMetTests = WOMatQARec<WO_MAT_QA_PROFILE$>
RecQAMetSlots = WOMatQARec<WO_MAT_QA_SLOT$>
// Locate the desired stage, profile/test, and slot in the record.
RecPos = ''
For each RecQAMetStage in RecQAMetStages using @VM setting vPos
RecQAMetTest = RecQAMetTests<0, vPos>
RecQAMetSlot = RecQAMetSlots<0, vPos>
If ( (RecQAMetStage EQ QAMetStage) and (RecQAMetTest EQ QAMetProfile) and (RecQAMetSlot EQ QAMetSlot) ) then
// Found the position in the record
RecPos = vPos
end
Until RecPos
Next RecQAMetStage
If RecPos then
// Locate the desired stage, profile/test, and slot in the spec QAMetData structure.
SpecQAMetStages = SpecQAMetData<COL$QA_MET_STAGE>
SpecQAMetTests = SpecQAMetData<COL$QA_MET_TEST>
SpecQAMetSlots = SpecQAMetData<COL$QA_MET_SLOT>
For each SpecQAMetStage in SpecQAMetStages using @VM setting vPos
SpecQAMetTest = SpecQAMetTests<0, vPos>
SpecQAMetSlot = SpecQAMetSlots<0, vPos>
SpecQAMetProfile = 1:SpecQAMetTest
SpecPos = ''
If ( (SpecQAMetStage EQ QAMetStage) and (SpecQAMetProfile EQ QAMetProfile) and (SpecQAMetSlot EQ QAMetSlot) ) then
// Found the posotion in the spec QAMetData structure
SpecPos = vPos
end
Until SpecPos
Next SpecQAMetStage
If SpecPos then
// Update the limits and recipe
WOMatQARec<WO_MAT_QA_RECIPE$, RecPos> = SpecQAMetData<COL$QA_MET_RECIPE, SpecPos>
WOMatQARec<WO_MAT_QA_RECIPE_PATTERN$, RecPos> = SpecQAMetData<COL$QA_MET_RECIPE_PATTERN, SpecPos>
WOMatQARec<WO_MAT_QA_MIN$, RecPos> = SpecQAMetData<COL$QA_MET_MIN, SpecPos>
WOMatQARec<WO_MAT_QA_MAX$, RecPos> = SpecQAMetData<COL$QA_MET_MAX, SpecPos>
WOMatQARec<WO_MAT_QA_REACT_SCHED$, RecPos> = SpecQAMetData<COL$QA_MET_REACT_SCHED, SpecPos>
WOMatQARec<WO_MAT_QA_PHASE_MIN$, RecPos> = SpecQAMetData<COL$QA_MET_PHASE_MIN, SpecPos>
Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAKey, WOMatQARec, True$, True$, True$)
If Error_Services('HasError') then ErrorMsg = Error_Services('GetMessage')
end else
ErrorMsg = 'Failed to find desired stage, test, and slot in spec QAMetData structure.'
end
end else
ErrorMsg = 'Failed to find desired stage, test, and slot in WO_MAT_QA record.'
end
end else
// Error reading WO_MAT_QA record
ErrorMsg = Error_Services('GetMessage')
end
end else
ErrorMsg = 'Error retrieving QAMetData from obj_Prod_Spec.'
end
end else
// Error reading PROD_SPEC record
ErrorMsg = Error_Services('GetMessage')
end
end else
ErrorMsg = 'Failed to find PSNo in WO_STEP record ':WOStepKey:'.'
end
end else
ErrorMsg = 'Null WOMatQAKey, QAMetStage, QAMetProfile, or QAMetSlot passed into service.'
end
If ErrorMsg EQ '' then
Response = True$
end else
Response = False$
Error_Services('Add', 'Error in ':Service:' service. ':ErrorMsg)
end
End Service
Service UpdateAllQAMetrologyLimits(WOMatQAKey)
ErrorMsg = ''
If WOMatQAKey NE '' then
WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey)
RecStages = WOMatQARec<WO_MAT_QA_STAGE$>
RecProfiles = WOMatQARec<WO_MAT_QA_PROFILE$>
RecSlots = WOMatQARec<WO_MAT_QA_SLOT$>
For each RecStage in RecStages using @VM setting vPos
RecProfile = RecProfiles<0, vPos>
RecSlot = RecSlots<0, vPos>
PSN_Services('UpdateQAMetrologyLimits', WOMatQAKey, RecStage, RecProfile, RecSlot)
If Error_Services('HasError') then ErrorMsg = Error_Services('GetMessage')
Next RecStage
end else
ErrorMsg = 'Null WOMatQAKey passed into service.'
end
If ErrorMsg EQ '' then
Response = True$
end else
Response = False$
Error_Services('Add', 'Error in ':Service:' service. ':ErrorMsg)
end
end service
Service UpdateAllQAMetrologyRecord(WOMatQAKey, stageToUpdate)
ErrorMsg = ''
If WOMatQAKey NE '' then
WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey)
WOStepKey = Field(WOMatQAKey, '*', 1) : '*1'
PSNo = Xlate('WO_STEP', WOStepKey, 'PROD_SPEC_ID', 'X')
PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo)
CurrTestCount = DCOUNT(WOMatQARec<1>, @VM)
SpecQAMetData = obj_Prod_Spec('GetQAMet',PSNo:@RM:PSRec)
for each SpecTest in SpecQAMetData<1> using @VM setting vPos then
If (WOMatQARec<1,vPos> EQ 'QA' OR WOMatQARec<1,vPos> EQ '') then
WOMatQARec<1,vPos> = SpecQAMetData<1,vPos>
if SpecQAMetData<2,vPos> EQ 'ADE' then SpecQAMetData<2,vPos> = '1ADE'
if SpecQAMetData<2,vPos> EQ 'THICK_ONLY' then SpecQAMetData<2,vPos> = '1THICK_ONLY'
if SpecQAMetData<2,vPos> EQ 'CRES' then SpecQAMetData<2,vPos> = '1CRES'
WOMatQARec<2,vPos> = SpecQAMetData<2,vPos>
WOMatQARec<3,vPos> = SpecQAMetData<3,vPos>
WOMatQARec<4,vPos> = SpecQAMetData<4,vPos>
WOMatQARec<5,vPos> = SpecQAMetData<5,vPos>
WOMatQARec<6,vPos> = SpecQAMetData<6,vPos>
WOMatQARec<7,vPos> = SpecQAMetData<7,vPos>
WOMatQARec<8,vPos> = SpecQAMetData<8,vPos>
WOMatQARec<9,vPos> = SpecQAMetData<9,vPos>
WOMatQARec<16,vPos> = SpecQAMetData<14,vPos>
WOMatQARec<26,vPos> = 0
end
Next SpecTest
Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAKey, WOMatQARec, True$, True$, True$)
end else
ErrorMsg = 'Null WOMatQAKey passed into service.'
end
If ErrorMsg EQ '' then
Response = True$
end else
Response = False$
Error_Services('Add', 'Error in ':Service:' service. ':ErrorMsg)
end
end service
Service UpdateRDSMetrologyLimits(RDSNo)
If RDSNo NE '' then
If RowExists('RDS', RDSNo) then
PSNo = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X')
If PSNo NE '' then
RDSTestKeys = Xlate('RDS', RDSNo, 'RDS_TEST_KEYS', 'X')
If RDSTestKeys NE '' then
For each RDSTestKey in RDSTestKeys using @VM setting vPos
// Code below adapted from obj_RDS_Test('Create')
RDSTestRec = Database_Services('ReadDataRow', 'RDS_TEST', RDSTestKey)
If Error_Services('NoError') then
LayerSet = RDSTestRec<RDS_TEST_LS_ID$>
Zone = RDSTestRec<RDS_TEST_ZONE$>
LayerSpecs = obj_Prod_Spec('GetLayerProp',PSNo:@RM:LayerSet:@RM:1) ;* Last parameter specifies no output conversion on return data
LayerSpecs = FIELD(LayerSpecs,@FM,2,99) ;* Returns with the layer set ID in the first field of each line
IF Not(Get_Status(errCode)) then
WaferSize = XLATE( 'PROD_SPEC', PSNo, 'SUB_WAFER_SIZE', 'X' )
SubOrientation = XLATE('PROD_SPEC',PSNo,'SUB_ORIENTATION','X')
ResUnits = LayerSpecs<PRS_LAYER_RES_UNITS$>
ReactorType = XLATE('PROD_SPEC',PSNo,PROD_SPEC_REACTOR_TYPE$,'X')
ThickFilmMet = XLATE('PROD_SPEC',PSNo,PROD_SPEC_THICKFILM_MET$,'X') ;* Added 1/16/2009 JCH
RDSTestRec<RDS_TEST_RDS_NO$> = RDSNo
RDSTestRec<RDS_TEST_LS_ID$> = LayerSet
RDSTestRec<RDS_TEST_ZONE$> = Zone
RDSTestRec<RDS_TEST_WAFER_SIZE$> = WaferSize
RDSTestRec<RDS_TEST_SUB_ORIENTATION$> = SubOrientation
RDSTestRec<RDS_TEST_SPEC_DOPANT$> = LayerSpecs<PRS_LAYER_DOPANT$>
RDSTestRec<RDS_TEST_SPEC_RECIPE$> = LayerSpecs<PRS_LAYER_RECIPE$>
RDSTestRec<RDS_TEST_SPEC_RECIPE_NAME$> = LayerSpecs<PRS_LAYER_RECIPE_NAME$>
RDSTestRec<RDS_TEST_SPEC_THICK_MIN$> = LayerSpecs<PRS_LAYER_THICK_MIN$>
RDSTestRec<RDS_TEST_SPEC_THICK_TARGET$> = LayerSpecs<PRS_LAYER_THICK_TARGET$>
RDSTestRec<RDS_TEST_SPEC_THICK_MAX$> = LayerSpecs<PRS_LAYER_THICK_MAX$>
RDSTestRec<RDS_TEST_SPEC_THICK_UNITS$> = LayerSpecs<PRS_LAYER_THICK_UNITS$>
RDSTestRec<RDS_TEST_SPEC_RES_MIN$> = LayerSpecs<PRS_LAYER_RES_MIN$>
RDSTestRec<RDS_TEST_SPEC_RES_TARGET$> = LayerSpecs<PRS_LAYER_RES_TARGET$>
RDSTestRec<RDS_TEST_SPEC_RES_MAX$> = LayerSpecs<PRS_LAYER_RES_MAX$>
RDSTestRec<RDS_TEST_SPEC_RES_UNITS$> = LayerSpecs<PRS_LAYER_RES_UNITS$>
RDSTestRec<RDS_TEST_SPEC_CON_MIN$> = LayerSpecs<PRS_LAYER_CONC_MIN$>
RDSTestRec<RDS_TEST_SPEC_CON_TARGET$> = LayerSpecs<PRS_LAYER_CONC_TARGET$>
RDSTestRec<RDS_TEST_SPEC_CON_MAX$> = LayerSpecs<PRS_LAYER_CONC_MAX$>
RDSTestRec<RDS_TEST_SPEC_CON_UNITS$> = LayerSpecs<PRS_LAYER_CONC_UNITS$>
RDSTestRec<RDS_TEST_SPEC_STRESS_MIN$> = LayerSpecs<PRS_LAYER_STRESS_MIN$>
RDSTestRec<RDS_TEST_SPEC_STRESS_MAX$> = LayerSpecs<PRS_LAYER_STRESS_MAX$>
RDSTestRec<RDS_TEST_SPEC_TRANS$> = LayerSpecs<PRS_LAYER_TRANS_SPEC$>
RDSTestRec<RDS_TEST_SPEC_CRES_MIN$> = LayerSpecs<PRS_LAYER_CRES_MIN$>
RDSTestRec<RDS_TEST_SPEC_CRES_TARGET$> = LayerSpecs<PRS_LAYER_CRES_TARGET$>
RDSTestRec<RDS_TEST_SPEC_CRES_MAX$> = LayerSpecs<PRS_LAYER_CRES_MAX$>
RDSTestRec<RDS_TEST_SPEC_CRES_UNITS$> = LayerSpecs<PRS_LAYER_CRES_UNITS$>
FOR A = 11 TO 19
RDSTestRec<A> = LayerSpecs<PRS_LAYER_THICK_MEASUREMENT$,A-10>
NEXT A
FOR A = 24 TO 32
RDSTestRec<A> = LayerSpecs<PRS_LAYER_RES_MEASUREMENT$,A-23>
NEXT A
FOR A = 37 TO 45
RDSTestRec<A> = LayerSpecs<PRS_LAYER_CONC_MEASUREMENT$,A-36>
NEXT A
FOR A = 50 to 58
RDSTestRec<A> = LayerSpecs<PRS_LAYER_STRESS_MEASUREMENT$,A-49>
NEXT A
FOR A = 121 TO 129
RDSTestRec<A> = LayerSpecs<PRS_LAYER_CRES_MEASUREMENT$,A-120>
NEXT A
RDSTestRec<RDS_TEST_SPEC_THICK_MPATTERN$> = LayerSpecs<PRS_LAYER_THICK_MEASUREMENT$,PRS_MPATTERN$>
RDSTestRec<RDS_TEST_SPEC_RES_MPATTERN$> = LayerSpecs<PRS_LAYER_RES_MEASUREMENT$,PRS_MPATTERN$>
RDSTestRec<RDS_TEST_SPEC_CON_MPATTERN$> = LayerSpecs<PRS_LAYER_CONC_MEASUREMENT$,PRS_MPATTERN$>
RDSTestRec<RDS_TEST_SPEC_STRESS_MPATTERN$> = LayerSpecs<PRS_LAYER_STRESS_MEASUREMENT$,PRS_MPATTERN$>
RDSTestRec<RDS_TEST_SPEC_CRES_MPATTERN$> = LayerSpecs<PRS_LAYER_CRES_MEASUREMENT$,PRS_MPATTERN$>
RDSTestRec<RDS_TEST_REACTOR_TYPE$> = ReactorType
IF ReactorType = 'P' OR ReactorType = 'EPP' OR ThickFilmMet = 1 THEN
SpecMap = XLATE('PROD_SPEC',PSNo,PROD_SPEC_TEST_POINT_MAP$,'X') ;* Added 4/8/2009 JCH new field in PROD_SPEC
IF SpecMap NE '' THEN
RDSTestRec<RDS_TEST_TEST_POINT_MAP$> = SpecMap
END ELSE
;* Added ThickFilmMet check - 1/16/2009 JCH
AllTargetThicks = XLATE('PROD_SPEC',PSNo,'THICK_TARGET_ALL','X')
TargetCnt = COUNT(AllTargetThicks,@VM) + (AllTargetThicks NE '')
BEGIN CASE
CASE TargetCnt = 2
CombinedThick = SUM(AllTargetThicks)
CASE TargetCnt = 1 OR TargetCnt = 3
CombinedThick = AllTargetThicks[-1,'B':@VM]
END CASE
IF OCONV(CombinedThick,'MD2') > '65.0' THEN
RDSTestRec<RDS_TEST_TEST_POINT_MAP$> = 'FTIR_T'
END ELSE
RDSTestRec<RDS_TEST_TEST_POINT_MAP$> = 'FTIR'
END
END
END ELSE
RDSTestRec<RDS_TEST_TEST_POINT_MAP$> = 'ASM17' ;* 17 Point linear test pattern until PROD_SPEC is updated support other types
END
Database_Services('WriteDataRow', 'RDS_TEST', RDSTestKey, RDSTestRec)
end else
Error_Services('Add', 'Error in ':Service:' service. Error calling obj_Prod_Spec("GetLayerProp")')
end
end
Next RDSTestKey
end else
Error_Services('Add', 'Error in ':Service:' serivce. No RDS_TEST records found for RDS record ':RDSNo:'.')
end
end else
Error_Services('Add', 'Error in ':Service:' serivce. Null PSNo returned for RDS record ':RDSNo:'.')
end
end else
Error_Services('Add', 'Error in ':Service:' serivce. RDS record ':RDSNo:' does not exist.')
end
end else
Error_Services('Add', 'Error in ':Service:' serivce. Null RDSNo passed in.')
end
end service
Service ConvertRecordToJSON(KeyID, Record, ItemURL)
jsonRecord = ''
If KeyID NE '' then
If Record EQ '' then Record = Database_Services('ReadDataRow', 'PROD_SPEC', KeyID)
If Error_Services('NoError') then
@DICT = Database_Services('GetTableHandle', 'DICT.PROD_SPEC')
@ID = KeyID
@RECORD = Record
If SRP_JSON(objJSON, 'New', 'Object') then
If SRP_JSON(objProdSpec, 'New', 'Object') then
SRP_JSON(objProdSpec, 'SetValue', 'keyId', @ID)
SRP_JSON(objProdSpec, 'SetValue', 'specType', OConv({SPEC_TYPE}, '[SPEC_TYPE_CONV]'))
SRP_JSON(objProdSpec, 'SetValue', 'status', OConv({STATUS}, '[PROD_SPEC_STATUS_CONV]'))
SRP_JSON(objProdSpec, 'SetValue', 'minutesPerWafer', OConv({MINUTES_PER_WAFER}, 'MD3'))
SRP_JSON(objProdSpec, 'SetValue', 'proveInTime', OConv({PROVEIN_MIN}, 'MD3,'))
SRP_JSON(objProdSpec, 'SetValue', 'layerType', {LAYER_TYPE})
SRP_JSON(objProdSpec, 'SetValue', 'reactorType', OConv({REACTOR_TYPE}, '[REACT_TYPE_CONV,OPSREF]'))
SRP_JSON(objProdSpec, 'SetValue', 'susceptorType', {SUSCEPTOR_TYPE})
SRP_JSON(objProdSpec, 'SetValue', 'tubePressureType', {TUBE_PRESSURE_TYPE})
ProdVerNos = {PROD_VER_NO}
CustEpiKeys = {CEP_KEYS}
StageKeys = {STAGE}
QAMetStages = {QA_MET_STAGE}
QAMetTests = {QA_MET_TEST}
QAMetProps = {QA_MET_PROP}
QAMetPropDescs = {QA_MET_PROP_DESC}
QAMetToolClasses = {QA_MET_TOOL_CLASS}
QAMetRecipes = {QA_MET_RECIPE}
QAMetRecipePatterns = {QA_MET_RECIPE_PATTERN}
QAMetMins = {QA_MET_MIN}
QAMetMaxes = {QA_MET_MAX}
QAPhaseMins = {QA_MET_PHASE_MIN}
QAMetSlots = {QA_MET_SLOT}
QAMetWfrQtys = {QA_MET_WFR_QTY}
QAMetReactScheds = {QA_MET_REACT_SCHED}
QAMetIntervals = {QA_MET_INTERVAL}
QAMetStarts = {QA_MET_START}
QAMetSeqs = {QA_MET_SEQUENCE}
// Add recipe layer object array
If SRP_JSON(objLayerArray, 'New', 'Array') then
LayerNos = {LAYER_NO}
LayerIDs = {LS_ID}
LayerTypes = {LS_TYPE}
LayerRecipes = {LS_RECIPE}
LayerDopants = {LS_DOPANT}
LayerThickMins = OConv({LS_THICK_MIN}, '[MET_PROP_CONV,THICK]')
LayerThickTargets = OConv({LS_THICK_TARG}, '[MET_PROP_CONV,THICK]')
LayerThickMaxes = OConv({LS_THICK_MAX}, '[MET_PROP_CONV,THICK]')
LayerThickUnits = {LS_THICK_UNITS}
LayerThickAMins = OConv({LS_THICKA_MIN}, '[MET_PROP_CONV,THICKA]')
LayerThickATargets = OConv({LS_THICKA_TARG}, '[MET_PROP_CONV,THICKA]')
LayerThickAMaxes = OConv({LS_THICKA_MAX}, '[MET_PROP_CONV,THICKA]')
LayerThickAUnits = {LS_THICKA_UNITS}
LayerResMins = OConv({LS_RES_MIN}, '[MET_PROP_CONV,RES]')
LayerResTargets = OConv({LS_RES_TARG}, '[MET_PROP_CONV,RES]')
LayerResMaxes = OConv({LS_RES_MAX}, '[MET_PROP_CONV,RES]')
LayerResUnits = {LS_RES_UNITS}
LayerSResMins = OConv({LS_SRES_MIN}, '[MET_PROP_CONV,SRES]')
LayerSResTargets = OConv({LS_SRES_TARG}, '[MET_PROP_CONV,SRES]')
LayerSResMaxes = OConv({LS_SRES_MAX}, '[MET_PROP_CONV,SRES]')
LayerSResUnits = {LS_SRES_UNITS}
If LayerNos NE '' then
For each LayerNo in LayerNos using @VM setting vPos
If SRP_JSON(objLayer, 'New', 'Object') then
SRP_JSON(objLayer, 'SetValue', 'layerNo', layerNo)
SRP_JSON(objLayer, 'SetValue', 'layerId', LayerIDs<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerType', LayerTypes<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerRecipe', LayerRecipes<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerDopant', LayerDopants<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerThickMin', LayerThickMins<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerThickTarget', LayerThickTargets<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerThickMax', LayerThickMaxes<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerThickUnits', LayerThickUnits<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerThickAMin', LayerThickAMins<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerThickATarget', LayerThickATargets<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerThickAMaxes', LayerThickAMaxes<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerThickAUnits', LayerThickAUnits<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerResMin', LayerResMins<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerResTarget', LayerResTargets<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerResMax', LayerResMaxes<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerResUnits', LayerResUnits<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerSResMin', LayerSResMins<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerSResTarget', LayerSResTargets<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerSResMax', LayerSResMaxes<0, vPos>)
SRP_JSON(objLayer, 'SetValue', 'layerSResUnits', LayerSResUnits<0, vPos>)
SRP_JSON(objLayerArray, 'Add', objLayer)
SRP_JSON(objLayer, 'Release')
end
Next LayerNo
end
SRP_JSON(objProdSpec, 'Set', 'recipeLayers', objLayerArray)
SRP_JSON(objLayerArray, 'Release')
end
// Add Prod Ver object array
If ProdVerNos NE '' then
If SRP_JSON(objProdVerArray, 'New', 'Array') then
For each ProdVerNo in ProdVerNos using @VM
ProdVerJSON = Prod_Ver_Services('ConvertRecordToJSON', ProdVerNo)
If SRP_JSON(objProdVer, 'Parse', ProdVerJSON) EQ '' then
objTemp = SRP_JSON(objProdVer, 'Get', 'prodVer')
SRP_JSON(objProdVerArray, 'Add', objTemp)
SRP_JSON(objTemp, 'Release')
SRP_JSON(objProdVer, 'Release')
end
Next ProdVerNo
SRP_JSON(objProdSpec, 'Set', 'prodVers', objProdVerArray)
SRP_JSON(objProdVerArray, 'Release')
end
end
// Epi Part object array
EpiPartNo = {EPI_PART_NO}
If EpiPartNo NE '' then
If SRP_JSON(objEpiPart, 'New', 'Object') then
SRP_JSON(objEpiPart, 'SetValue', 'keyID', EpiPartNo)
WaferSize = Xlate('EPI_PART', EpiPartNo, 'SUB_WAFER_SIZE', 'X')
SRP_JSON(objEpiPart, 'SetValue', 'waferSize', WaferSize)
SRP_JSON(objProdSpec, 'Set', 'epiPart', objEpiPart)
SRP_JSON(objEpiPart, 'Release')
end
end
// Cust Epi Part object array
If CustEpiKeys NE '' then
If SRP_JSON(objCustEpiArray, 'New', 'Array') then
For each CustEpiKey in CustEpiKeys using @VM
CustEpiJSON = Cust_Epi_Part_Services('ConvertRecordToJSON', CustEpiKey)
If SRP_JSON(objCustEpi, 'Parse', CustEpiJSON) EQ '' then
objTemp = SRP_JSON(objCustEpi, 'Get', 'custEpiPart')
SRP_JSON(objCustEpiArray, 'Add', objTemp)
SRP_JSON(objTemp, 'Release')
SRP_JSON(objCustEpi, 'Release')
end
Next CustEpiKey
end
SRP_JSON(objProdSpec, 'Set', 'custEpiParts', objCustEpiArray)
SRP_JSON(objCustEpiArray, 'Release')
end
// Add PRS Stage (Run Stage) object array
If StageKeys NE '' then
If SRP_JSON(objStageArray, 'New', 'Array') then
For each StageKey in StageKeys using @VM
PRSKey = KeyID:'*':StageKey
PRSStageJSON = PRS_Stage_Services('ConvertRecordToJSON', PRSKey)
If SRP_JSON(objPRSStage, 'Parse', PRSStageJSON) EQ '' then
objTemp = SRP_JSON(objPRSStage, 'Get', 'prsStage')
SRP_JSON(objStageArray, 'Add', objTemp)
SRP_JSON(objTemp, 'Release')
SRP_JSON(objPRSStage, 'Release')
end
Next StageKey
end
SRP_JSON(objProdSpec, 'Set', 'prsStages', objStageArray)
SRP_JSON(objStageArray, 'Release')
end
SRP_JSON(objJSON, 'Set', 'prodSpec', objProdSpec)
SRP_JSON(objProdSpec, 'Release')
end
If itemURL NE '' then
// The itemURL was passed in so add HAL+JSON properties.
// Create the _links property and then all link objects needed for this resource.
If SRP_JSON(objLinks, 'New', 'Object') then
// Create a self link.
If SRP_JSON(objLink, 'New', 'Object') then
SRP_JSON(objLink, 'SetValue', 'href', ItemURL, 'String')
SRP_JSON(objLink, 'SetValue', 'title', 'Self', 'String')
SRP_JSON(objLinks, 'Set', 'self', objLink)
SRP_JSON(objLink, 'Release')
end
SRP_JSON(objJSON, 'Set', '_links', objLinks)
SRP_JSON(objLinks, 'Release')
end
// Create the _class property for this resource.
SRP_JSON(objJSON, 'SetValue', '_class', 'resource')
end
jsonRecord = SRP_JSON(objJSON, 'Stringify', 'Styled')
SRP_JSON(objJSON, 'Release')
end else
Error_Services('Add', 'Unable to create JSON representation in the ' : Service : ' service.')
end
end
end else
Error_Services('Add', 'KeyID argument was missing in the ' : Service : ' service.')
end
Response = jsonRecord
end service
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* * * * * *
CheckAdHoc:
* * * * * *
StageRecKey = PSNo: '*' : Stage
StageRec = XLATE('PRS_STAGE', StageRecKey, '', 'X')
IF StageRec<PRS_STAGE_CLEAN_SIG_REQ$> EQ 1 then
GoSub CheckCleansParms
IF Error_Services('GetMessage') NE '' then
Return
end
end
IF StageRec<PRS_STAGE_INSP_SIG_REQ$> EQ 1 then
GoSub CheckVisualParms
IF Error_Services('GetMessage') NE '' then
Return
end
end
IF StageRec<PRS_STAGE_SURFSCAN_SIG_REQ$> EQ 1 then
GoSub CheckSurfaceParms
IF Error_Services('GetMessage') NE '' then
Return
end
end
QAMetTests = StageRec<PRS_STAGE_MET_TEST$>
IF QAMetTests<1,1> NE '' then
GoSub CheckQAMetParms
IF Error_Services('GetMessage') NE '' then
Return
end
end
return