COMPILE FUNCTION obj_RDS_Test(Method,Parms,Override) /* Methods for RDS Metrology (RDS_TEST) table 02/14/2006 JCH - Initial Coding Properties: Methods: New() ;* Creates New Records */ #pragma precomp SRP_PreCompiler DECLARE SUBROUTINE Set_Status, Msg, obj_Tables, ErrMsg, Btree.Extract, Post_Metrology_Manual_Data_Entry_Log, SRP_Stopwatch Declare subroutine Memory_Services, Environment_Services, Logging_Services, Database_Services DECLARE FUNCTION Get_Status, Msg, Utility, obj_Tables, Dialog_Box, obj_WO_Log, NextKey, SRP_Encode DECLARE FUNCTION obj_Prod_Spec, obj_RDS_Test, obj_Popup, Database_Services, SRP_Array, Memory_Services Declare function Environment_Services, Logging_Services, Error_Services $insert LOGICAL $INSERT MSG_EQUATES $INSERT RDS_EQU $INSERT RDS_LAYER_EQUATES $INSERT RDS_TEST_EQUATES $INSERT RDS_TEST_PROP_EQUATES $INSERT PRS_LAYER_EQU $INSERT PROD_SPEC_EQU $INSERT TW_USE_EQUATES $INSERT CUST_EPI_PART_EQUATES $INSERT REACT_RUN_EQUATES EQU STAT_AVG$ TO 1 EQU STAT_STDV$ TO 2 EQU STAT_UNIF$ TO 3 EQU STAT_MIN$ TO 4 * This section used in PushProps method EQU UNIT$THICK TO CHAR(230):'m' ;* Microns EQU UNIT$THICKA TO CHAR(143) ;* Angstroms EQU UNIT$RES TO CHAR(234):'-cm' ;* Ohms.Cm EQU UNIT$SRES TO CHAR(234):'/':CHAR(220) ;* Ohms/Square EQU UNIT$CRES TO CHAR(234):'-cm' ;* Ohms.Cm EQU UNIT$CONC TO 'CM-3' ;* Carriers.Cubic Centimeter EQU UNIT$STRESS TO 'dyne/cm-2' ;* Dyne/Square Centimeter EQU UNIT$BOW TO CHAR(230):'m' ;* Microns EQU UNIT$TRANS TO CHAR(230):'m' ;* Microns EQU SHEETRHO_SPEC_UNITS$ TO 'ê/Ü' EQU RES_SPEC_UNITS$ TO \EA2D636D\ EQU STAT_MAX$ TO 5 EQU CRLF$ TO \0D0A\ ErrTitle = 'Error in Stored Procedure "obj_RDS_Test"' ErrorMsg = '' IF NOT(ASSIGNED(Method)) THEN ErrorMsg = 'Unassigned parameter "Method" passed to subroutine' IF NOT(ASSIGNED(Parms)) THEN Parms = '' IF NOT(ASSIGNED(Override)) then Override = False$ IF ErrorMsg NE '' THEN Set_Status(-1,ErrTitle:@SVM:ErrorMsg) RETURN '' END Result = '' BEGIN CASE CASE Method = 'Create' ; GOSUB Create CASE Method = 'CalcStats' ; GOSUB CalcStats CASE Method = 'Resistivity' ; GOSUB Resistivity CASE Method = 'CopyStats' ; GOSUB CopyStats CASE Method = 'Delete' ; GOSUB Delete CASE Method = 'CalcMissing' ; GOSUB CalcMissing ;* Used for the conversion process CASE Method = 'OutOfSpec' ; GOSUB OutOfSpec CASE Method = 'TestWfrCount' ; GOSUB TestWfrCount CASE Method = 'PrimeWfrCount' ; GOSUB PrimeWfrCount CASE Method = 'ProdTestCount' ; GOSUB ProdTestCount CASE Method = 'CustTWCount' ; GOSUB CustTWCount CASE Method = 'ReclaimCount' ; GOSUB ReclaimCount CASE Method = 'SetReadSet' ; GOSUB SetReadSet CASE Method = 'GetReadSet' ; GOSUB GetReadSet CASE Method = 'SetZone' ; GOSUB SetZone CASE Method = 'TWSignedOff' ; GOSUB TWSignedOff CASE Method = 'ExpReadings' ; GOSUB ExpReadings CASE Method = 'ExpTower' ; GOSUB ExpTower CASE Method = 'ExpIR' ; GOSUB ExpIR CASE Method = 'RefreshSpecs' ; GOSUB RefreshSpecs CASE Method = 'TestComplete' ; GOSUB TestComplete CASE Method = 'TestPropKeys' ; GOSUB TestPropKeys CASE Method = 'PushProps' ; GOSUB PushProps CASE Method = 'ExpCOA' ; GOSUB ExpCOA CASE 1 ErrorMsg = 'Unknown Method ':QUOTE(Method):' passed to routine.' END CASE IF ErrorMsg NE '' THEN Set_Status(-1,ErrTitle:@SVM:ErrorMsg) RETURN '' END RETURN Result * * * * * * * Create: * * * * * * * RDSNo = Parms[1,@RM] LayerSet = Parms[COL2()+1,@RM] PSNId = Parms[COL2()+1,@RM] Zone = Parms[COL2()+1,@RM] IF RDSNo = '' THEN ErrorMsg = 'Null parameter "RDSNo" passed to routine (':Method:').' ; RETURN IF LayerSet = '' THEN ErrorMsg = 'Null parameter "LayerSet" passed to routine (':Method:').' ; RETURN IF PSNId = '' THEN PSNId = XLATE('RDS',RDSNo, RDS_PROD_SPEC_ID$ ,'X') IF PSNId = '' THEN ErrorMsg = 'Null parameter "PSNId" passed to routine (':Method:').' ; RETURN END END LayerSpecs = obj_Prod_Spec('GetLayerProp',PSNId:@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 Get_Status(errCode) THEN RETURN WaferSize = XLATE( 'PROD_SPEC', PSNId, 'SUB_WAFER_SIZE', 'X' ) SubOrientation = XLATE('PROD_SPEC',PSNId,'SUB_ORIENTATION','X') ResUnits = LayerSpecs ReactorType = XLATE('PROD_SPEC',PSNId,PROD_SPEC_REACTOR_TYPE$,'X') ThickFilmMet = XLATE('PROD_SPEC',PSNId,PROD_SPEC_THICKFILM_MET$,'X') ;* Added 1/16/2009 JCH RDSTestRec = '' RDSTestRec = RDSNo RDSTestRec = LayerSet RDSTestRec = Zone RDSTestRec = WaferSize RDSTestRec = SubOrientation RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs FOR A = 11 TO 19 RDSTestRec = LayerSpecs NEXT A FOR A = 24 TO 32 RDSTestRec = LayerSpecs NEXT A FOR A = 37 TO 45 RDSTestRec = LayerSpecs NEXT A FOR A = 50 to 58 RDSTestRec = LayerSpecs NEXT A FOR A = 121 TO 129 RDSTestRec = LayerSpecs NEXT A RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = ReactorType IF ReactorType = 'P' OR ReactorType = 'EPP' OR ThickFilmMet = 1 THEN SpecMap = XLATE('PROD_SPEC',PSNId,PROD_SPEC_TEST_POINT_MAP$,'X') ;* Added 4/8/2009 JCH new field in PROD_SPEC IF SpecMap NE '' THEN RDSTestRec = SpecMap END ELSE ;* Added ThickFilmMet check - 1/16/2009 JCH AllTargetThicks = XLATE('PROD_SPEC',PSNId,'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 = 'FTIR_T' END ELSE RDSTestRec = 'FTIR' END END END ELSE RDSTestRec = 'ASM17' ;* 17 Point linear test pattern until PROD_SPEC is updated support other types END RDSTestKey = NextKey('RDS_TEST') obj_Tables('WriteRec','RDS_TEST':@RM:RDSTestKey:@RM:@RM:RDSTestRec) Result = RDSTestKey RETURN * * * * * * * CalcStats: * * * * * * * IF NOT(ASSIGNED(Readings)) THEN Readings = Parms[1,@RM] Conversion = Parms[COL2()+1,@RM] END IF Conversion = '' THEN ErrorMsg = 'Null parameter "Conversion" passed to routine (':Method:').' IF ErrorMsg THEN RETURN thisReadings = Readings StatAvg = '' StatStdv = '' StatUnif = '' StatMin = '' StatMax = '' StatRange = '' StatRangePcnt = '' AvgCount = 0 AvgTotal = 0 ReadCount = COUNT(thisReadings,@VM) + (thisReadings NE '') FOR I = 1 TO ReadCount thisReading = ThisReadings<1,I> IF thisReading NE '' AND thisReading NE 0.00 THEN AvgCount += 1 AvgTotal += thisReading IF thisReading _LEX StatMin OR StatMin = '' THEN StatMin = thisReading IF thisReading _GEX StatMax OR StatMax = '' THEN StatMax = thisReading END NEXT I IF AvgCount > 0 THEN StatAvg = AvgTotal/AvgCount Mean = AvgTotal/AvgCount StatRange = StatMax - StatMin StatRangePcnt = (StatRange/Mean)*100 SumDiffSq = 0 FOR I = 1 TO ReadCount thisReading = thisReadings<1,I> IF thisReading NE '' THEN *SumDiffSq += ( thisReading - Mean )**2 SumDiffSq += ( thisReading - Mean ) * ( thisReading - Mean ) END NEXT I IF SumDiffSq _GEX 0.00 AND AvgCount > 1 THEN StatStdv = Sqrt( SumDiffSq / (AvgCount - 1) ) END IF SumDiffSq _EQX 0 AND AvgCount > 1 THEN StatStdv = 0 END IF StatMin NE '' AND StatMax NE '' AND StatMin _GEX 0 AND StatMin _GEX 0 THEN StatUnif = OCONV(((StatMax - StatMin)/(StatMax + StatMin))*10000, 'MD2' ) END StatAvg = ICONV(StatAvg,Conversion) StatStdv = ICONV(StatStdv,'MD4') StatMin = ICONV(StatMin,Conversion) StatMax = ICONV(StatMax,Conversion) StatRange = ICONV(StatRange,Conversion) StatRangePcnt = ICONV(StatRangePcnt,'MD4') Result = OCONV(StatAvg,Conversion):@RM Result := OCONV(StatStdv,'MD4'):@RM Result := StatUnif:@RM Result := OCONV(StatMin,Conversion):@RM Result := OCONV(StatMax,Conversion):@RM Result := OCONV(StatRange,Conversion):@RM Result := OCONV(StatRangePcnt,'MD4S%') RETURN * * * * * * * Resistivity: * * * * * * * IF NOT(ASSIGNED(RDSTestKey)) THEN * Get parameters if not called from another method in this program RDSTestKey = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] NoConversion = Parms[COL2()+1,@RM] END IF RDSTestKey = '' THEN RETURN IF RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') ReactorType = RDSTestRec RDSNo = RDSTestRec SheetRhoReads = OCONV(RDSTestRec,'MD3') ThickReads = OCONV(RDSTestRec,'MD2') ThickOvergrowAvg = OCONV(RDSTestRec,'MD2') ReadCnt = COUNT(SheetRhoReads,@VM) + (SheetRhoReads NE '') IF ReadCnt = '' THEN ReadCnt = COUNT(ThickReads,@VM) + (ThickReads NE '') END FOR I = 1 TO ReadCnt SheetRhoRead = SheetRhoReads<1,I> CalcValue = ThickReads<1,I> ThickRead = OCONV(ICONV((CalcValue),'MD2'),'MD2') IF ThickOvergrowAvg NE '' THEN ThickRead = ThickOverGrowAvg IF SheetRhoRead = '' AND ThickRead = '' THEN Result<1,I> = '' END ELSE IF SheetRhoRead NE 0 AND ThickRead NE 0 THEN IF NoConversion THEN IF ReactorType = 'P' OR ReactorType = 'EPP' THEN Result<1,I> = ICONV((SheetRhoRead * ThickRead)/10000,'MD3')*10 END ELSE Result<1,I> = ICONV((SheetRhoRead * ThickRead)/10000,'MD4') END END ELSE IF ReactorType = 'P' OR ReactorType = 'EPP' THEN Result<1,I> = OCONV(ICONV((SheetRhoRead * ThickRead/10000)*10,'MD3'),'MD4') END ELSE Result<1,I> = OCONV(ICONV((SheetRhoRead * ThickRead/10000),'MD4'),'MD4') END END END ELSE Result<1,I> = '' END END NEXT I RETURN * * * * * * * CopyStats: * * * * * * * SourceRDSTestKeys = Parms[1,@RM] DestRDSTestKeys = Parms[COL2()+1,@RM] IF SourceRDSTestKeys = '' THEN ErrorMsg = 'Null parameter "SourceRDSTestKeys" passed to routine. (':Method:')' IF DestRDSTestKeys = '' THEN ErrorMsg = 'Null parameter "DestRDSTestKeys" passed to routine. (':Method:')' RTParms = 'RDS_TEST' LockedRDSTestKeys = '' FOR I = 1 TO COUNT(DestRDSTestKeys,@VM) + (DestRDSTestKeys NE '') DestRDSTestKey = DestRDSTestKeys<1,I> RTParms = FieldStore(RTParms, @RM, 2, 1, DestRDSTestKey) // No longer lock records when copying metrology. This avoids unnecessary overhad and contention for a simple // operation. - 08/04/2017 * obj_Tables('LockRec',RTParms) * IF Get_Status(errCode) THEN * FOR N = 1 TO COUNT(LockedRDSTestKeys,@VM) + (LockedRDSTestKeys NE '') * RTParms = FieldStore(RTParms, @RM, 2, 1, LockedRDSTestKeys<1,N>) * obj_Tables('UnlockRec',RTParms) ;* Unlock everything locked up to here * NEXT N * ErrorMsg = 'Unable to lock RDS_TEST ':QUOTE(DestRDSTestKey):' for Update.' * * RETURN * END ELSE LockedRDSTestKeys<1,I> = DestRDSTestKey * END NEXT I * RDSTestTableVar = FIELD(RTParms,@RM,3) RDSTestTableVar = Database_Services('GetTableHandle', 'RDS_TEST') RDSTestKeyCount = DCount(LockedRDSTestKeys, @VM) FOR I = 1 TO RDSTestKeyCount LockedRDSTestKey = LockedRDSTestKeys<1,I> READ DestRDSTestRec FROM RDSTestTableVar,LockedRDSTestKey THEN SourceRDSTestKey = SourceRDSTestKeys<1,I> SourceRDSTestRec = XLATE('RDS_TEST',SourceRDSTestKey,'','X') DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec DestRDSTestRec = SourceRDSTestRec RTParms = FieldStore(RTParms, @RM, 2, 1, LockedRDSTestKey) RTParms = FieldStore(RTParms, @RM, 4, 1, DestRDSTestRec) * obj_Tables('WriteRec',RTParms) ;* Write and unlock RDS_TEST records obj_Tables('WriteOnlyRec',RTParms) ;* Write but don't worry about unlocking. END NEXT I RETURN * * * * * * * Delete: * * * * * * * MetKeys = Parms[1,@RM] IF MetKeys = '' THEN RETURN CONVERT @VM:@SVM TO @FM:@FM IN MetKeys OPEN 'RDS_TEST' TO MetFile ELSE ErrorMsg = 'Unable to open "RDS_TEST" table.(':Method:').' RETURN END OPEN 'TW_USE' TO UseFile ELSE ErrorMsg = 'Unable to open "TW_USE" table.(':Method:').' RETURN END KeyCnt = COUNT(MetKeys,@FM) + (MetKeys NE '') FOR I = 1 TO KeyCnt MetKey = MetKeys TWUseKeys = XLATE('RDS_TEST',MetKey,RDS_TEST_TW_USE_ID$,'X') UseRecordsCleared = 1 UseCnt = COUNT(TWUseKeys,@VM) + (TWUseKeys NE '') FOR N = 1 TO UseCnt TWUseKey = TWUseKeys<1,N> DELETE UseFile,TWUseKey ELSE UseRecordsCleared = 0 NEXT N IF UseRecordsCleared = 1 THEN DELETE MetFile,MetKeys ELSE NULL END NEXT I RETURN * * * * * * * CalcMissing: * * * * * * * RDSTestRec = Parms[1,@RM] IF RDSTestRec = '' THEN RETURN * Calculate the resistivity values SheetRhoReads = OCONV(RDSTestRec,'MD3') ThickReads = OCONV(RDSTestRec,'MD2') ThickOvergrowAvg = OCONV(RDSTestRec,'MD2') ReactorType = RdsTestRec IF RDSTestRec = RES_SPEC_UNITS$ THEN * Calculate Resistivity Reads and Statistics ReadCnt = COUNT(SheetRhoReads,@VM) + (SheetRhoReads NE '') Readings = '' FOR I = 1 TO ReadCnt SheetRhoRead = SheetRhoReads<1,I> ThickRead = ThickReads<1,I> IF ThickOvergrowAvg _NEX '' THEN ThickRead = ThickOverGrowAvg IF SheetRhoRead _NEX 0 AND SheetRhoRead NE '' AND ThickRead _NEX 0 AND ThickRead NE '' THEN IF ReactorType = 'P' OR ReactorType = 'EPP' THEN Readings<1,I> = OCONV(ICONV((SheetRhoRead * ThickRead/10000),'MD3')*10,'MD4Z') ;* Crutch for EpiPRO with to tight of specs 7/3/2008 JCH END ELSE Readings<1,I> = OCONV(ICONV((SheetRhoRead * ThickRead/10000),'MD4'),'MD4Z') END END ELSE Readings<1,I> = '' END NEXT I IF Readings NE '' THEN Results = obj_RDS_Test('CalcStats',Readings:@RM:'MD4') CONVERT @RM TO @FM IN Results RDSTestRec = ICONV(Results[1,@FM],'MD4') RDSTestRec = ICONV(Results[COL2()+1,@FM],'MD4') RDSTestRec = ICONV(Results[COL2()+1,@FM],'MD2') RDSTestRec = ICONV(Results[COL2()+1,@FM],'MD4') RDSTestRec = ICONV(Results[COL2()+1,@FM],'MD4') END END ELSE * Calculate SheetRho statistics Readings = OCONV(RDSTestRec,'MD3') IF Readings NE '' THEN Results = obj_RDS_Test('CalcStats',Readings:@RM:'MD3') CONVERT @RM TO @FM IN Results RDSTestRec = ICONV(Results[1,@FM],'MD3') RDSTestRec = ICONV(Results[COL2()+1,@FM],'MD4') RDSTestRec = ICONV(Results[COL2()+1,@FM],'MD3') RDSTestRec = ICONV(Results[COL2()+1,@FM],'MD3') RDSTestRec = ICONV(Results[COL2()+1,@FM],'MD3') END END Result = RDSTestRec RETURN * * * * * * * OutOfSpec: * * * * * * * RDSTestKey = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKey = '' THEN RETURN IF RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') RDSNo = RdsTestRec LSId = RdsTestRec ReactorType = RdsTestRec NoConversion = 1 GOSUB Resistivity ;* Calculate Resistvity values ResReads = Result Result = '' SheetRhoReads = RDSTestRec ThickReads = RDSTestRec HgCvReads = RDSTestRec SpecThickMin = RDSTestRec SpecThickMax = RDSTestRec SpecResMin = RDSTestRec SpecResMax = RDSTestRec SpecResUnits = RDSTestRec ReadLineCnt = COUNT(ThickReads,@VM) + (ThickReads NE '') ThickSpecFlag = 0 SheetRhoSpecFlag = 0 ResistivitySpecFlag = 0 HgCvSpecFlag = 0 FOR I = 1 TO ReadLineCnt ThickVal = ThickReads<1,I> ThickVal = ICONV(ThickVal, "MD1") IF ThickVal NE '' THEN IF ThickVal > SpecThickMax OR ThickVal < SpecThickMin THEN ThickSpecFlag = 1 END IF SpecResUnits = SHEETRHO_SPEC_UNITS$ THEN ResVal = SheetRhoReads<1,I> IF ResVal NE '' THEN IF ResVal > SpecResMax OR ResVal < SpecResMin THEN SheetRhoSpecFlag = 1 END END IF SpecResUnits = RES_SPEC_UNITS$ THEN ResVal = ResReads<1,I> IF ResVal = 0 THEN ResVal = '' IF ResVal NE '' THEN IF ResVal > SpecResMax*10 OR ResVal < SpecResMin*10 THEN ResistivitySpecFlag = 1 END HgCvVal = HgCvReads<1,I> IF HgCvVal NE '' THEN IF HgCvVal > SpecResMax OR HgCvVal < SpecResMin THEN HgCvSpecFlag = 1 END END NEXT I ThickMinValue = RDSTestRec ThickMaxValue = RDSTestRec ThickMinValue = ICONV(ThickMinValue, "MD1") ThickMaxValue = ICONV(ThickMaxValue, "MD1") IF ThickMinValue < SpecThickMin AND ThickMinValue NE '' THEN ThickSpecFlag = 1 IF ThickMaxValue > SpecThickMax AND ThickMaxValue NE '' THEN ThickSpecFlag = 1 BEGIN CASE CASE SpecResUnits = SHEETRHO_SPEC_UNITS$ ResMinValue = RDSTestRec ResMaxValue = RDSTestRec IF ResMinValue < SpecResMin AND ResMinValue NE ''THEN SheetRhoSpecFlag = 1 IF ResMaxValue > SpecResMax AND ResMaxValue NE '' THEN SheetRhoSpecFlag = 1 CASE SpecResUnits = RES_SPEC_UNITS$ ResMinValue = RDSTestRec ResMaxValue = RDSTestRec SpecResMin = SpecResMin*10 SpecResMax = SpecResMax*10 IF ResMinValue < SpecResMin AND ResMinValue NE '' THEN ResistivitySpecFlag = 1 ;* Spec adjusted for Resistivity change to MD4 - JCH 7/1/2008 IF ResMaxValue > SpecResMax AND ResMaxValue NE '' THEN ResistivitySpecFlag = 1 ;* Spec adjusted for Resistivity change to MD4 - JCH 7/1/2008 HgCvMinValue = RDSTestRec HgCvMaxValue = RDSTestRec IF HgCvMinValue < SpecResMin AND HgCvMinValue NE '' THEN HgCvSpecFlag = 1 IF HgCvMaxValue > SpecResMax AND HgCvMaxValue NE '' THEN HgCvSpecFlag = 1 CASE 1 NULL END CASE ASETSpecFlag = 0 ASETResults = RDSTestRec IF ASETResults > 179 THEN ASETSpecFlag = 1 IF ThickSpecFlag OR SheetRhoSpecFlag OR ResistivitySpecFlag OR HgCvSpecFlag OR ASETSpecFlag THEN Result = 1 END ELSE Result = '' END RETURN Result * * * * * * * TestWfrCount: * * * * * * * RDSTestKeys = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKeys = '' THEN RETURN TestWfrCnt = 0 PopupData = XLATE('SYSREPOSPOPUPS','LSL2**TW_TYPES',8,'X') TestTypes = '' FOR I = 1 TO COUNT(PopupData,@VM) + (PopupData NE '') IF PopupData<1,I,3> NE 'PROD' AND PopupData<1,I,3> NE 'CUST'THEN TestTypes<1,-1> = PopupData<1,I,1> END NEXT I CONVERT @LOWER_CASE TO @UPPER_CASE IN TestTypes FOR N = 1 TO COUNT(RDSTestKeys,@VM) + (RDSTestKeys NE '') RDSTestKey = RDSTestKeys<1,N> IF N = 1 AND RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') END ELSE RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') END TWUseIDs = RDSTestRec IF TWUseIDs NE '' THEN TWTypes = XLATE('TW_USE',TWUseIDs,TW_USE_TW_TYPE$,'X') TWCnts = XLATE('TW_USE',TWUseIDs,TW_USE_TW_QTY$,'X') END ELSE TWTypes = RDSTestRec TWCnts = RDSTestRec END CONVERT @LOWER_CASE TO @UPPER_CASE IN TWTypes FOR I = 1 TO COUNT(TWTypes,@VM) + (TWTypes NE '') TWType = TWTypes<1,I> LOCATE TWType IN TestTypes USING @VM SETTING Dummy THEN TestWfrCnt += TWCnts<1,I> END NEXT I NEXT N IF TestWfrCnt > 0 THEN Result = TestWfrCnt ELSE Result = '' RETURN * * * * * * * PrimeWfrCount: * * * * * * * RDSTestKeys = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKeys = '' THEN RETURN TestWfrCnt = 0 PopupData = XLATE('SYSREPOSPOPUPS','LSL2**TW_TYPES',8,'X') PrimeTypes = '' FOR I = 1 TO COUNT(PopupData,@VM) + (PopupData NE '') IF PopupData<1,I,3> = 'PRIME' THEN PrimeTypes<1,-1> = PopupData<1,I,1> END NEXT I CONVERT @LOWER_CASE TO @UPPER_CASE IN PrimeTypes FOR N = 1 TO COUNT(RDSTestKeys,@VM) + (RDSTestKeys NE '') RDSTestKey = RDSTestKeys<1,N> IF N = 1 AND RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') END ELSE RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') END TWUseIDs = RDSTestRec IF TWUseIDs NE '' THEN TWTypes = XLATE('TW_USE',TWUseIDs,TW_USE_TW_TYPE$,'X') TWCnts = XLATE('TW_USE',TWUseIDs,TW_USE_TW_QTY$,'X') END ELSE TWTypes = RDSTestRec TWCnts = RDSTestRec END CONVERT @LOWER_CASE TO @UPPER_CASE IN TWTypes FOR I = 1 TO COUNT(TWTypes,@VM) + (TWTypes NE '') TWType = TWTypes<1,I> LOCATE TWType IN PrimeTypes USING @VM SETTING Dummy THEN TestWfrCnt += TWCnts<1,I> END NEXT I NEXT N IF TestWfrCnt > 0 THEN Result = TestWfrCnt ELSE Result = '' RETURN * * * * * * * ProdTestCount: * * * * * * * RDSTestKeys = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKeys = '' THEN RETURN RDSTestKeysHex = SRP_Encode(RDSTestKeys, 'HEX') If Memory_Services('IsValueExpired', RDSTestKeysHex, 1) then // Caching effectively disabled until further notice. // An unintended side effect of caching is stale data being displayed. ProdTypes = Memory_Services('GetValue', 'PROD_TW_TYPES') If ProdTypes EQ '' then PopupData = XLATE('SYSREPOSPOPUPS','LSL2**TW_TYPES',8,'X') ProdTypes = '' FOR I = 1 TO COUNT(PopupData,@VM) + (PopupData NE '') IF PopupData<1,I,3> = 'PROD' THEN ProdTypes<1,-1> = PopupData<1,I,1> END NEXT I CONVERT @LOWER_CASE TO @UPPER_CASE IN ProdTypes Memory_Services('SetValue', 'PROD_TW_TYPES', ProdTypes) end SRP_Stopwatch('Start', 'ProdTestCount-NoCache') ProdWfrCnt = 0 FOR N = 1 TO COUNT(RDSTestKeys,@VM) + (RDSTestKeys NE '') RDSTestKey = RDSTestKeys<1,N> IF N = 1 AND RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') END ELSE RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') END TWUseIDs = RDSTestRec IF TWUseIDs NE '' THEN TWTypes = XLATE('TW_USE',TWUseIDs,TW_USE_TW_TYPE$,'X') TWCnts = XLATE('TW_USE',TWUseIDs,TW_USE_TW_QTY$,'X') END ELSE TWTypes = RDSTestRec TWCnts = RDSTestRec END CONVERT @LOWER_CASE TO @UPPER_CASE IN TWTypes FOR I = 1 TO COUNT(TWTypes,@VM) + (TWTypes NE '') TWType = TWTypes<1,I> LOCATE TWType IN ProdTypes USING @VM SETTING Dummy THEN ProdWfrCnt += TWCnts<1,I> END NEXT I NEXT N IF ProdWfrCnt > 0 THEN Result = ProdWfrCnt ELSE Result = '' Memory_Services('SetValue', RDSTestKeysHex, Result) SRP_Stopwatch('Stop', 'ProdTestCount-NoCache') end else Result = Memory_Services('GetValue', RDSTestKeysHex) end RETURN * * * * * * * ReclaimCount: * * * * * * * RDSTestKeys = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKeys = '' THEN RETURN PopupData = XLATE('SYSREPOSPOPUPS','LSL2**TW_TYPES',8,'X') ReclTypes = '' FOR I = 1 TO COUNT(PopupData,@VM) + (PopupData NE '') IF PopupData<1,I,3> = 'RECL' THEN ReclTypes<1,-1> = PopupData<1,I,1> END NEXT I CONVERT @LOWER_CASE TO @UPPER_CASE IN ReclTypes ReclWfrCnt = 0 FOR N = 1 TO COUNT(RDSTestKeys,@VM) + (RDSTestKeys NE '') RDSTestKey = RDSTestKeys<1,N> IF N = 1 AND RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') END ELSE RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') END TWUseIDs = RDSTestRec IF TWUseIDs NE '' THEN TWTypes = XLATE('TW_USE',TWUseIDs,TW_USE_TW_TYPE$,'X') TWCnts = XLATE('TW_USE',TWUseIDs,TW_USE_TW_QTY$,'X') END ELSE TWTypes = RDSTestRec TWCnts = RDSTestRec END CONVERT @LOWER_CASE TO @UPPER_CASE IN TWTypes FOR I = 1 TO COUNT(TWTypes,@VM) + (TWTypes NE '') TWType = TWTypes<1,I> LOCATE TWType IN ReclTypes USING @VM SETTING Dummy THEN ReclWfrCnt += TWCnts<1,I> END NEXT I NEXT N IF ReclWfrCnt > 0 THEN Result = ReclWfrCnt ELSE Result = '' RETURN * * * * * * * CustTWCount: * * * * * * * RDSTestKeys = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKeys = '' THEN RETURN PopupData = XLATE('SYSREPOSPOPUPS','LSL2**TW_TYPES',8,'X') CustTypes = '' FOR I = 1 TO COUNT(PopupData,@VM) + (PopupData NE '') IF PopupData<1,I,3> = 'CUST' THEN CustTypes<1,-1> = PopupData<1,I,1> END NEXT I CustWfrCnt = 0 CONVERT @LOWER_CASE TO @UPPER_CASE IN CustTypes FOR N = 1 TO COUNT(RDSTestKeys,@VM) + (RDSTestKeys NE '') RDSTestKey = RDSTestKeys<1,N> IF N = 1 AND RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') END ELSE RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') END TWUseIDs = RDSTestRec IF TWUseIDs NE '' THEN TWTypes = XLATE('TW_USE',TWUseIDs,TW_USE_TW_TYPE$,'X') TWCnts = XLATE('TW_USE',TWUseIDs,TW_USE_TW_QTY$,'X') END ELSE TWTypes = RDSTestRec TWCnts = RDSTestRec END RDSNo = RDSTestRec WONo = XLATE('REACT_RUN',RDSNo,REACT_RUN_WO_NO$,'X') CustEpiPartKey = XLATE('WO_LOG',WONo,'CUST_EPI_PART_NO','X') TWRetInst = XLATE('CUST_EPI_PART',CustEpiPartKey,CUST_EPI_PART_TW_RET_INST$,'X') BEGIN CASE CASE TWRetInst = 'C' ;* Customer supplied only CONVERT @LOWER_CASE TO @UPPER_CASE IN TWTypes FOR I = 1 TO COUNT(TWTypes,@VM) + (TWTypes NE '') TWType = TWTypes<1,I> LOCATE TWType IN CustTypes USING @VM SETTING Dummy THEN CustWfrCnt += TWCnts<1,I> END NEXT I CASE TWRetInst = 'P' ;* Last good P+ and P- test wafers IF INDEX(TWTypes,'P+',1) THEN CustWfrCnt += 1 IF INDEX(TWTypes,'P-',1) THEN CustWfrCnt += 1 CASE TWRetInst = 'N' ;* None are sent to customer CustWfrCnt = 0 CASE TWRetInst = '' CustWfrCnt = 0 END CASE NEXT N IF CustWfrCnt > 0 THEN Result = CustWfrCnt ELSE Result = '' RETURN * * * * * * * GetReadSet: * * * * * * * MetNo = Parms[1,@RM] IF MetNo = '' THEN RETURN MetRec = XLATE('RDS_TEST',MetNo,'','X') IF MetRec = '' THEN RETURN TestPointMap = MetRec TestPoints = XLATE('RDS_TEST',MetNo,'TEST_POINTS','X') ThickReads = OCONV(MetRec,'MD2') SheetRhoReads = OCONV(MetRec,'MD3') HgCV1Reads = OCONV(MetRec,'MD3') LineOut = 0 FOR I = 1 TO 17 IF ThickReads<1,I> NE '' OR SheetRhoReads<1,I> NE '' OR HgCV1Reads<1,I> NE '' THEN LineOut += 1 Result<1,LineOut> = TestPoints<1,LineOut> Result<2,LineOut> = ThickReads<1,I> Result<3,LineOut> = SheetRhoReads<1,I> Result<4,LineOut> = HgCV1Reads<1,I> END NEXT I RETURN * * * * * * * SetReadSet: * * * * * * * MetNo = Parms[1,@RM] ThickReads = Parms[COL2()+1,@RM] SheetRhoReads = Parms[COL2()+1,@RM] HgCV1Reads = Parms[COL2()+1,@RM] IF MetNo = '' THEN ErrorMsg = 'Null parameter "MetNo" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN Readings = ThickReads Conversion = 'MD2' GOSUB CalcStats ThickAvg = Result[1,@RM] ThickStdev = Result[COL2()+1,@RM] ThickUnif = Result[COL2()+1,@RM] ThickMin = Result[COL2()+1,@RM] ThickMax = Result[COL2()+1,@RM] ThickRange = Result[COL2()+1,@RM] ThickRangePcnt = Result[COL2()+1,@RM] Result = '' Readings = SheetRhoReads Conversion = 'MD3' GOSUB CalcStats SheetRhoAvg = Result[1,@RM] SheetRhoStdev = Result[COL2()+1,@RM] SheetRhoUnif = Result[COL2()+1,@RM] SheetRhoMin = Result[COL2()+1,@RM] SheetRhoMax = Result[COL2()+1,@RM] SheetRhoRange = Result[COL2()+1,@RM] SheetRhoRangePcnt = Result[COL2()+1,@RM] Result = '' Readings = HgCV1Reads Conversion = 'MD3' GOSUB CalcStats HgCV1Avg = Result[1,@RM] HgCV1Stdev = Result[COL2()+1,@RM] HgCV1Unif = Result[COL2()+1,@RM] HgCV1Min = Result[COL2()+1,@RM] HgCV1Max = Result[COL2()+1,@RM] HgCV1Range = Result[COL2()+1,@RM] HgCV1RangePcnt = Result[COL2()+1,@RM] thisThickReads = ICONV(ThickReads,'MD2') thisSheetRhoReads = ICONV(SheetRhoReads,'MD3') thisHgCV1Reads = ICONV(HgCV1Reads,'MD3') Set_Status(0) RTParms = 'RDS_TEST':@RM:MetNo * MetRec = obj_Tables('ReadRec',RTParms) MetRec = Database_Services('ReadDataRow', 'RDS_TEST', MetNo) IF Get_Status(errCode) THEN ErrorMsg = 'Unable to read RDS_TEST record ':QUOTE(MetNo):' for SetReadSet update.' RETURN END MetRec = ICONV(ThickAvg,'MD2') MetRec = ICONV(ThickStdev,'MD4') MetRec = ICONV(ThickUnif,'MD2') MetRec = ICONV(ThickMin,'MD2') MetRec = ICONV(ThickMax,'MD2') MetRec = ICONV(ThickRange,'MD2') MetRec = ICONV(ThickRangePcnt,'MD4S%') MetRec = ICONV(SheetRhoAvg,'MD3') MetRec = ICONV(SheetRhoStdev,'MD4') MetRec = ICONV(SheetRhoUnif,'MD2') MetRec = ICONV(SheetRhoMin,'MD3') MetRec = ICONV(SheetRhoMax,'MD3') MetRec = ICONV(SheetRhoRange,'MD3') MetRec = ICONV(SheetRhoRangePcnt,'MD2') MetRec = ICONV(HgCV1Avg,'MD3') MetRec = ICONV(HgCV1Stdev,'MD4') MetRec = ICONV(HgCV1Unif,'MD2') MetRec = ICONV(HgCV1Min,'MD3') MetRec = ICONV(HgCV1Max,'MD3') MetRec = ICONV(HgCV1Range,'MD3') MetRec = ICONV(HgCV1RangePcnt,'MD4') TestPointMap = MetRec TestPoints = XLATE('TEST_POINT_MAP',TestPointMap,2,'X') TPCnt = COUNT(TestPoints,@VM) + (TestPoints NE '') DispCnt = 17 BlankLineCnt = (DispCnt - TPCnt)/2 IF BlankLineCnt > 0 THEN ThickReads = STR(@VM,BlankLineCnt):thisThickReads:STR(@VM,BlankLineCnt) SheetRhoReads = STR(@VM,BlankLineCnt):thisSheetRhoReads:STR(@VM,BlankLineCnt) HgCV1Reads = STR(@VM,BlankLineCnt):thisHgCV1Reads:STR(@VM,BlankLineCnt) END RDSNo = MetRec // Check for thickness changes and log if necessary. If SRP_Array('Clean', MetRec, 'TrimTrailing', @VM) NE SRP_Array('Clean', ThickReads, 'TrimTrailing', @VM) then Post_Metrology_Manual_Data_Entry_Log(@USER4, 'Thickness', RDSNo : ' / ' : MetNo) end // Save the changes MetRec = ThickReads // Check for resistivity changes and log if necessary. If SRP_Array('Clean', MetRec, 'TrimTrailing', @VM) NE SRP_Array('Clean', SheetRhoReads, 'TrimTrailing', @VM) then Post_Metrology_Manual_Data_Entry_Log(@USER4, 'Resistivity', RDSNo : ' / ' : MetNo) end // Save the changes MetRec = SheetRhoReads // Check for HgRes changes and log if necessary. If SRP_Array('Clean', MetRec, 'TrimTrailing', @VM) NE SRP_Array('Clean', HgCV1Reads, 'TrimTrailing', @VM) then Post_Metrology_Manual_Data_Entry_Log(@USER4, 'HgRes', RDSNo : ' / ' : MetNo) end // Save the changes MetRec = HgCV1Reads Parms = MetRec GOSUB CalcMissing ;* Calcs the resistivity MetRec = Result Result = '' // Set the override flag if passed in. MetRec = Override RTParms = FieldStore(RTParms, @RM, 4, 1, MetRec) Database_Services('WriteDataRow', 'RDS_TEST', MetNo, MetRec, True$, False$, True$) * obj_Tables('WriteRec',RTParms) RETURN * * * * * * * SetZone: * * * * * * * MetNo = Parms[1,@RM] Zone = Parms[COL2()+1,@RM] IF MetNo = '' THEN ErrorMsg = 'Null parameter "MetNo" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN Set_Status(0) RTParms = 'RDS_TEST':@RM:MetNo MetRec = obj_Tables('ReadRec',RTParms) IF Get_Status(errCode) THEN ErrorMsg = 'Unable to read RDS_TEST record ':QUOTE(MetNo):' for SetReadSet update.' RETURN END MetRec = Zone RTParms = FieldStore(RTParms, @RM, 4, 1, MetRec) obj_Tables('WriteRec',RTParms) RETURN * * * * * * * TWSignedOff: * * * * * * * RDSTestKey = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKey = '' THEN RETURN IF RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') TWUseIDs = RDSTestRec TWCnts = XLATE('TW_USE',TWUseIDs,TW_USE_TW_QTY$,'X') TWSigs = XLATE('TW_USE',TWUseIDs,TW_USE_SIGNATURE$,'X') IF TWCnts = '' THEN *Result = 0 Result = 1 END ELSE Result = 1 FOR I = 1 TO COUNT(TWCnts,@VM) + (TWCnts NE '') IF TWCnts<1,I> NE '' AND TWSigs<1,I> = '' THEN Result = 0 END UNTIL Result = 0 NEXT I END RETURN * * * * * * * ExpReadings: * * * * * * * RDSTestKey = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] ExpFormat = Parms[COL2()+1,@RM] IF RDSTestKey = '' THEN RETURN IF RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') NoConversion = 1 GOSUB Resistivity Resistivities = Result Result = '' TestPoints = XLATE('TEST_POINT_MAP',RDSTestRec,2,'X') TPCnt = COUNT(TestPoints,@VM) +(TestPoints NE '') DispCnt = 17 BlankLineCnt = (DispCnt - TPCnt)/2 IF BlankLineCnt > 0 THEN TestPoints = STR(@VM,BlankLineCnt):TestPoints:STR(@VM,BlankLineCnt) END ThickReads = RDSTestRec SheetRhoReads = RDSTestRec Hgcv1Reads = RDSTestRec ExpTestPoints = '' ExpThickReads = '' ExpSheetRhoReads = '' ExpHgcv1Reads = '' ExpResistivities = '' ResLine = 0 FOR I = 1 TO 17 ThickRead = ThickReads<1,I> SheetRhoRead = SheetRhoReads<1,I> Hgcv1Read = Hgcv1Reads<1,I> IF ThickRead = '' AND SheetRhoRead = '' AND Hgcv1Read = '' ELSE ResLine += 1 ExpTestPoints<1,ResLine> = TestPoints<1,I> ExpThickReads<1,ResLine> = ThickReads<1,I> ExpSheetRhoReads<1,ResLine> = SheetRhoReads<1,I> ExpHgcv1Reads<1,ResLine> = Hgcv1Reads<1,I> ExpResistivities<1,ResLine> = Resistivities<1,I> END NEXT I IF ExpFormat = 1 THEN ExpThickReads = OCONV(ExpThickReads,'MD2') ExpSheetRhoReads = OCONV(ExpSheetRhoReads,'MD3') ExpHgcv1Reads = OCONV(ExpHgcv1Reads,'MD3') ExpResistivities = OCONV(ExpResistivities,'MD4Z') END Result = ExpTestPoints:@FM:ExpThickReads:@FM:ExpSheetRhoReads:@FM:ExpHgcv1Reads:@FM:ExpResistivities RETURN * * * * * * * ExpTower: * * * * * * * * Customer Specific data Export RDSTestKey = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKey = '' THEN RETURN IF RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') NoConversion = 1 GOSUB Resistivity Resistivities = Result Result = '' ThickReads = RDSTestRec SheetRhoReads = RDSTestRec Hgcv1Reads = RDSTestRec ResSampSize = '' ThickSampSize = '' SheetRhoSampSize = '' Hgcv1SampSize = '' FOR I = 1 TO 17 IF Resistivities<1,I> NE '' THEN ResSampSize += 1 IF ThickReads<1,I> NE '' THEN ThickSampSize += 1 IF SheetRhoReads<1,I> NE '' THEN SheetRhoSampSize += 1 IF Hgcv1Reads<1,I> NE '' THEN Hgcv1SampSize += 1 NEXT I IF ThickSampSize > 0 THEN NewLine = '"Thickness"':@VM NewLine := OCONV(RDSTestRec,'MD2'):@VM NewLine := OCONV(RDSTestRec,'MD4'):@VM NewLine := OCONV(RDSTestRec,'MD2'):@VM NewLine := OCONV(RDSTestRec,'MD2'):@VM NewLine := ThickSampSize:@VM NewLine := OCONV(RDSTestRec,'MD2'):@VM NewLine := OCONV(RDSTestRec,'MD2'):@VM NewLine := '':@VM NewLine := '':@VM NewLine := '"um"' Result<-1> = NewLine END /* IF SheetRhoSampSize > 0 THEN NewLine = '"SheetRho"':@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := OCONV(RDSTestRec,'MD4'):@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := SheetRhoSampSize:@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := '':@VM NewLine := '':@VM NewLine := '"Ohm-cm"' Result<-1> = NewLine END */ IF Hgcv1SampSize > 0 THEN NewLine = '"Resistivity-HgCv1"':@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := OCONV(RDSTestRec,'MD4'):@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := Hgcv1SampSize:@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := '':@VM NewLine := '':@VM NewLine := '"Ohm-cm"' Result<-1> = NewLine END IF ResSampSize > 0 THEN NewLine = '"Resistivity-Calc"':@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := OCONV(RDSTestRec,'MD4'):@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := ResSampSize:@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := OCONV(RDSTestRec,'MD3'):@VM NewLine := '':@VM NewLine := '':@VM NewLine := '"Ohm-cm"' Result<-1> = NewLine END RETURN * * * * * * * ExpIR: * * * * * * * * Customer Specific data Export RDSTestKey = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKey = '' THEN RETURN IF RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') NoConversion = 1 GOSUB Resistivity Resistivities = Result Result = '' ThickReads = RDSTestRec SheetRhoReads = RDSTestRec Hgcv1Reads = RDSTestRec ResSampSize = '' ThickSampSize = '' SheetRhoSampSize = '' Hgcv1SampSize = '' Line = '' FOR I = 1 TO 17 IF ThickReads<1,I> = '' THEN Line<1,I> = '' END ELSE Line<1,I> = OCONV(ThickReads<1,I>,'MD2') END IF Resistivities<1,I> = '' THEN Line<1,I+17> = '' END ELSE Line<1,I+17> = OCONV(Resistivities<1,I>,'MD4') END IF Hgcv1Reads<1,I> = '' THEN Line<1,I+34> = '' END ELSE Line<1,I+34> = OCONV(Hgcv1Reads<1,I>,'MD3') END NEXT I Result<-1> = Line RETURN * * * * * * * ExpCOA: * * * * * * * RDSTestKey = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKey = '' THEN RETURN IF RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') NoConversion = 1 GOSUB Resistivity Resistivities = Result Result = '' ThickReads = RDSTestRec SheetRhoReads = RDSTestRec Hgcv1Reads = RDSTestRec TimeSTamp = RDSTestRec *JRO New Reads ThickAvg = OCONV(RDSTestRec, 'MD2') ThickStdDev = OCONV(RDSTestRec, 'MD4') ThickMin = OCONV(RDSTestRec, 'MD2') ThickMax = OCONV(RDSTestRec, 'MD2') SheetRhoReads = RDSTestRec Hgcv1Reads = RDSTestRec if RDSTestRec NE '' THEN ResAvg = OCONV(RDSTestRec, 'MD4') ResStdDev = OCONV(RDSTestRec, 'MD4') ResMin = OCONV(RDSTestRec, 'MD4') ResMax = OCONV(RDSTestRec, 'MD4') End else ResAvg = OCONV(RDSTestRec, 'MD3') ResStdDev = OCONV(RDSTestRec, 'MD3') ResMin = OCONV(RDSTestRec, 'MD3') ResMax = OCONV(RDSTestRec, 'MD3') end ResSampSize = '' ThickSampSize = '' SheetRhoSampSize = '' Hgcv1SampSize = '' Line = '' Line = ThickAvg : @VM : ThickStdDev : @VM : ThickMin : @VM : ThickMax: @VM : ResAvg: @VM :ResStdDev: @VM :ResMin: @VM :ResMax Result = Line RETURN * * * * * * * RefreshSpecs: * * * * * * * MetNo = Parms[1,@RM] IF MetNo = '' THEN RETURN TableVar = '' OtParms = 'RDS_TEST':@RM:MetNo:@RM:TableVar RDSTestRec = obj_Tables('ReadRec',OtParms) IF Get_Status(errCode) THEN RETURN RDSNo = RDSTestRec PSNId = XLATE('REACT_RUN',RDSNo,'PS_NO','X') LayerSet = RDSTestRec LayerSpecs = obj_Prod_Spec('GetLayerProp',PSNId:@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 Get_Status(errCode) THEN obj_Tables('UnlockRec',OtParms) RETURN END RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs RDSTestRec = LayerSpecs FOR A = 11 TO 19 RDSTestRec = LayerSpecs NEXT A FOR A = 24 TO 32 RDSTestRec = LayerSpecs NEXT A FOR A = 37 TO 45 RDSTestRec = LayerSpecs NEXT A FOR A = 50 to 58 RDSTestRec = LayerSpecs NEXT A FOR A = 121 TO 129 RDSTestRec = LayerSpecs NEXT A WaferSize = XLATE( 'PROD_SPEC', PSNId, 'SUB_WAFER_SIZE', 'X' ) SubOrientation = XLATE('PROD_SPEC',PSNId,'SUB_ORIENTATION','X') ResUnits = LayerSpecs ReactorType = XLATE('PROD_SPEC',PSNId,PROD_SPEC_REACTOR_TYPE$,'X') ThickFilmMet = XLATE('PROD_SPEC',PSNId,PROD_SPEC_THICKFILM_MET$,'X') ;* Added 1/16/2009 JCH RDSTestRec = ReactorType IF ReactorType = 'P' OR ReactorType = 'EPP' OR ThickFilmMet = 1 THEN SpecMap = XLATE('PROD_SPEC',PSNId,PROD_SPEC_TEST_POINT_MAP$,'X') ;* Added 4/8/2009 JCH new field in PROD_SPEC IF SpecMap NE '' THEN RDSTestRec = SpecMap END ELSE ;* Added ThickFilmMet check - 1/16/2009 JCH AllTargetThicks = XLATE('PROD_SPEC',PSNId,'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 = 'FTIR_T' END ELSE RDSTestRec = 'FTIR' END END END ELSE RDSTestRec = 'ASM17' ;* 17 Point linear test pattern until PROD_SPEC is updated support other types END OtParms = FieldStore(OtParms,@RM,4,1,RDSTestRec) obj_Tables('WriteRec',OtParms) *obj_Tables('UnlockRec',OtParms) RETURN * * * * * * * TestComplete: * * * * * * * RDSTestKey = Parms[1,@RM] RDSTestRec = Parms[COL2()+1,@RM] IF RDSTestKey = '' THEN RETURN IF RDSTestRec = '' THEN RDSTestRec = XLATE('RDS_TEST',RDSTestKey,'','X') RDSNo = RdsTestRec LSId = RdsTestRec ReactorType = RdsTestRec NoConversion = 1 GOSUB Resistivity ;* Calculate Resistvity values ResReads = Result Result = '' SheetRhoReads = RDSTestRec ThickReads = RDSTestRec HgCvReads = RDSTestRec SpecThickMin = RDSTestRec SpecThickMax = RDSTestRec SpecThickTool = RDSTestRec SpecResMin = RDSTestRec SpecResMax = RDSTestRec SpecResTool = RDSTestRec SpecResUnits = RDSTestRec ReadLineCnt = COUNT(ThickReads,@VM) + (ThickReads NE '') ThickCompFlag = 0 SheetRhoCompFlag = 0 ResistivityCompFlag = 0 HgCvCompFlag = 0 FOR I = 1 TO ReadLineCnt ThickVal = ThickReads<1,I> IF ThickVal NE '' OR SpecThickTool = 'SRP' THEN ThickCompFlag = 1 END IF SpecResUnits = SHEETRHO_SPEC_UNITS$ THEN ResVal = SheetRhoReads<1,I> IF ResVal NE '' THEN SheetRhoCompFlag = 1 END END IF SpecResUnits = RES_SPEC_UNITS$ THEN ResVal = ResReads<1,I> IF ResVal = 0 THEN ResVal = '' IF ResVal NE '' THEN ResistivityCompFlag = 1 END HgCvVal = HgCvReads<1,I> IF HgCvVal NE '' THEN HgCvCompFlag = 1 END END NEXT I IF SpecResTool = 'SRP' THEN SheetRhoCompFlag = 1 ResistivityCompFlag = 1 END ReadingsComp = 0 BEGIN CASE CASE SpecResUnits = SHEETRHO_SPEC_UNITS$ IF ThickCompFlag = 1 AND SheetRhoCompFlag = 1 THEN ReadingsComp = 1 END CASE SpecResUnits = RES_SPEC_UNITS$ IF ThickCompFlag = 1 AND ( HgCvCompFlag = 1 OR ResistivityCompFlag = 1) THEN ReadingsComp = 1 END CASE 1 NULL END CASE GOSUB TWSignedOff TWCompFlag = Result Result = '' IF SpecResUnits NE '' THEN IF ReadingsComp = 1 AND TWCompFlag = 1 THEN Result = 1 END ELSE Result = 0 END END ELSE Result = TWCompFlag END RETURN Result * * * * * * * TestPropKeys: * * * * * * * MetNo = Parms[1,@RM] IF MetNo = '' THEN RETURN OPEN 'DICT.RDS_TEST_PROP' TO DictVar ELSE RETURN Btree.Extract('MET_NO':@VM:MetNo:@FM, 'RDS_TEST_PROP', DictVar, TestPropKeys, '', '') SortedProps = obj_Popup('AllCodes','MET_PROPERTY':@RM:2) ;* All Met Prop codes in the MET_PROPERTY popup tpCnt = COUNT(TestPropKeys,@VM) + (TestPropKeys NE '') SortedKeys = '' FOR I = 1 TO tpCnt TestPropKey = TestPropKeys<1,I> TestProp = FIELD(TestPropKey,'*',2) LOCATE TestProp IN SortedProps USING @VM SETTING Pos THEN SortedKeys = INSERT(SortedKeys,1,Pos,0,TestPropKey) END NEXT I CONVERT @VM TO ' ' IN SortedKeys SortedKeys = TRIM(SortedKeys) CONVERT ' ' TO @VM IN SortedKeys Result = SortedKeys RETURN * * * * * * * PushProps: * * * * * * * MetNo = Parms[1,@RM] IF MetNo = '' THEN RETURN MetRec = XLATE('RDS_TEST',MetNo,'','X') IF MetRec = '' THEN RETURN RETURN IF MetRec NE '' THEN IF MetRec = UNIT$THICK THEN Prop = 'THICK' END ELSE Prop = 'THICKA' END MetPropKey = MetNo:'*':Prop MetPropRec = '' MetPropRec = ICONV(OCONV(MetRec,'MD2'),'[MET_PROP_CONV,':Prop:']') MetPropRec = ICONV(OCONV(MetRec,'MD2'),'[MET_PROP_CONV,':Prop:']') MetPropRec = ICONV(OCONV(MetRec,'MD2'),'[MET_PROP_CONV,':Prop:']') MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = ICONV(OCONV(MetRec,'MD2'),'[MET_PROP_CONV,':Prop:']') OtParms = 'RDS_TEST_PROP':@RM:MetPropKey:@RM:@RM:MetPropRec obj_Tables('WriteRec',OtParms) END ;* End of Thickness Property IF MetRec NE '' THEN Prop = '' IF MetRec = UNIT$RES THEN Prop = 'RES' END IF MetRec = UNIT$SRES THEN Prop = 'SRES' END MetPropKey = MetNo:'*':Prop MetPropRec = '' MetPropRec = ICONV(OCONV(MetRec,'MD3'),'[MET_PROP_CONV,':Prop:']') MetPropRec = ICONV(OCONV(MetRec,'MD3'),'[MET_PROP_CONV,':Prop:']') MetPropRec = ICONV(OCONV(MetRec,'MD3'),'[MET_PROP_CONV,':Prop:']') MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec IF Prop = 'RES' THEN MetPropRec = ICONV(OCONV(MetRec,'MD3'),'[MET_PROP_CONV,':Prop:']') END ELSE MetPropRec = ICONV(OCONV(MetRec,'MD3'),'[MET_PROP_CONV,':Prop:']') END OtParms = 'RDS_TEST_PROP':@RM:MetPropKey:@RM:@RM:MetPropRec obj_Tables('WriteRec',OtParms) END ;* End of RES or SRES Property IF MetRec NE '' THEN Prop = 'CRES' MetPropKey = MetNo:'*':Prop MetPropRec = '' MetPropRec = ICONV(OCONV(MetRec,'MD2'),'[MET_PROP_CONV,':Prop:']') MetPropRec = ICONV(OCONV(MetRec,'MD2'),'[MET_PROP_CONV,':Prop:']') MetPropRec = ICONV(OCONV(MetRec,'MD2'),'[MET_PROP_CONV,':Prop:']') MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = ICONV(OCONV(MetRec,'MD3'),'[MET_PROP_CONV,':Prop:']') OtParms = 'RDS_TEST_PROP':@RM:MetPropKey:@RM:@RM:MetPropRec obj_Tables('WriteRec',OtParms) END ;* End of CRES or HgCv Resistivity Property IF MetRec NE '' OR MetRec NE '' THEN Prop = 'CONC' MetPropKey = MetNo:'*':Prop MetPropRec = '' MetPropRec = ICONV(OCONV(MetRec,'MD2'),'[MET_PROP_CONV,':Prop:']') MetPropRec = ICONV(OCONV(MetRec,'MD2'),'[MET_PROP_CONV,':Prop:']') MetPropRec = ICONV(OCONV(MetRec,'MD2'),'[MET_PROP_CONV,':Prop:']') MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec OtParms = 'RDS_TEST_PROP':@RM:MetPropKey:@RM:@RM:MetPropRec obj_Tables('WriteRec',OtParms) END ;* End of Concentration Property IF MetRec NE '' OR MetRec NE '' THEN Prop = 'STRESS' MetPropKey = MetNo:'*':Prop MetPropRec = '' MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec MetPropRec = MetRec OtParms = 'RDS_TEST_PROP':@RM:MetPropKey:@RM:@RM:MetPropRec obj_Tables('WriteRec',OtParms) END ;* End of STRESS Property RETURN