1062 lines
75 KiB
Plaintext
1062 lines
75 KiB
Plaintext
Function Disposition_Services(@Service, @Params)
|
|
/***********************************************************************************************************************
|
|
|
|
Name : Disposition_Services
|
|
|
|
Description : Handler program for all Disposition services.
|
|
|
|
Notes : Application errors should be logged using the Error Services module. There are a few methodological
|
|
assumptions built into way errors are managed which are important to understand in order to properly
|
|
work with Error Services:
|
|
|
|
- The term 'top' refers to the originating procedure of a call stack and the term 'bottom' refers to
|
|
the last routine (or the current routine) within a call stack. Within the OpenInsight Debugger
|
|
this will appear backwards since the originating procedure always appears at the bottom of the
|
|
list and the current routine appears at the top of the list. We are using this orientation because
|
|
it is common to refer to the process of calling other procedures as 'drilling down'.
|
|
|
|
- The reason for defining the orientation of the call stack is because Error_Services allows for
|
|
multiple error conditions to be appended to an original error. In most cases this will happen when
|
|
a procedure at the bottom of the stack generates an error condition and then returns to its
|
|
calling procedure. This higher level procedure can optionally add more information relevant to
|
|
itself. This continues as the call stack 'bubbles' its way back to the top to where the
|
|
originating procedure is waiting.
|
|
|
|
- Native OpenInsight commands that handle errors (e.g., Set_Status, Set_FSError, Set_EventStatus)
|
|
preserve their error state until explicitly cleared. This can hinder the normal execution of code
|
|
since subsequent procedures (usually SSPs) will fail if a pre-existing error condition exists.
|
|
Our philosophy is that error conditions should automatically be cleared before a new procedure
|
|
is executed to avoid this problem. However, the nature of Basic+ does not make this easy to
|
|
automate for any given stored procedure. Therefore, if a stored procedure wants to conform to our
|
|
philosophy then it should include a call into the 'Clear' service request at the top of the
|
|
program. Alternatively this can be done through a common insert (see SERVICE_SETUP for example.)
|
|
|
|
- Service modules will use the SERVICE_SETUP insert and therefore automatically clear out any
|
|
error conditions that were set before.
|
|
|
|
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)
|
|
08/20/20 djs Original programmer.
|
|
|
|
|
|
***********************************************************************************************************************/
|
|
#pragma precomp SRP_PreCompiler
|
|
|
|
$insert SERVICE_SETUP
|
|
$insert REACT_RUN_EQUATES
|
|
$insert WO_WFR_EQUATES
|
|
$insert RUN_STAGE_WFR_EQUATES
|
|
$insert APP_INSERTS
|
|
|
|
Declare subroutine Error_Services, Database_Services, GaN_Services, Disposition_Services
|
|
Declare function Database_Services, Error_Services, DateTime, GaN_Services
|
|
|
|
GoToService else
|
|
Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.')
|
|
end
|
|
|
|
Return Response else ''
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Services
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// AutoDispositionRun
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service AutoDispositionRun(RDSNo)
|
|
|
|
If RDSNo NE '' then
|
|
ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo)
|
|
If Error_Services('NoError') then
|
|
InWfrIDs = ReactRunRec<REACT_RUN_IN_WFR_ID$>
|
|
For each WfrID in InWfrIDs using @VM
|
|
Disposition_Services('AutoDispositionWfr', WfrID)
|
|
Next WfrID
|
|
end
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// AutoDispositionWfr
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service AutoDispositionWfr(WfrID)
|
|
|
|
RDSNo = Xlate('WO_WFR', WfrID, 'RDS_NO', 'X')
|
|
PSNo = Xlate('REACT_RUN', RDSNo, 'PS_NO', 'X')
|
|
TechType = Xlate('PROD_SPEC', PSNo, 'TECH_TYPE', 'X')
|
|
|
|
Begin Case
|
|
|
|
Case TechType EQ 'P'
|
|
// Production
|
|
|
|
// Update missing and out of spec flags before performing auto disposition.
|
|
GaN_Services('UpdateDataFlags', RDSNo)
|
|
ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo)
|
|
OrigReactRunRec = ReactRunRec
|
|
NCRFlags = ReactRunRec<REACT_RUN_NCR_REQ$>
|
|
InWfrIDs = ReactRunRec<REACT_RUN_IN_WFR_ID$>
|
|
DispFlags = ReactRunRec<REACT_RUN_WFRS_DISP_READY$>
|
|
Grades = ReactRunRec<REACT_RUN_CARR_WFR_GRADE$>
|
|
Reasons = ReactRunRec<REACT_RUN_DISP_REASON$>
|
|
CharFlags = ReactRunRec<REACT_RUN_CHAR_WFR_FLAG$>
|
|
ShipFlags = ReactRunRec<REACT_RUN_CARR_WFR_SHIP$>
|
|
CritStages = ReactRunRec<REACT_RUN_GAN_CRITICAL_STAGES$>
|
|
WfrStages = ReactRunRec<REACT_RUN_WFR_STAGE$>
|
|
MissingDataFlags = ReactRunRec<REACT_RUN_DATA_MISSING$>
|
|
OutOfSpecFlags = ReactRunRec<REACT_RUN_DATA_OUT_OF_SPEC$>
|
|
ValidationDisFlags = ReactRunRec<REACT_RUN_MISSING_DATA_VALID_DISABLED$>
|
|
ScrapRDS = ReactRunRec<REACT_RUN_RUN_SCRAPPED$>
|
|
InternalFlags = ReactRunRec<REACT_RUN_INTERNAL$>
|
|
ExternalFlags = ReactRunRec<REACT_RUN_EXTERNAL$>
|
|
CharList = ReactRunRec<REACT_RUN_CHAR_LIST$>
|
|
RDSClosed = ReactRunRec<REACT_RUN_DISP_COMPLETE$>
|
|
AllWfrsComp = Gan_Services('ReadyToClose', RDSNo)
|
|
GaNMetStages = Database_Services('ReadDataRow', 'APP_INFO', 'GAN_MET_STAGES')
|
|
PSNo = Xlate('REACT_RUN', RDSNo, 'PS_NO', 'X')
|
|
ANKO = Xlate('PROD_SPEC', PSNo, 'ANKO', 'X')
|
|
|
|
Locate WfrID in InWfrIDs using @VM setting WaferPos then
|
|
CharFlag = CharFlags<0, WaferPos>
|
|
If CharFlag EQ True$ then
|
|
|
|
// Characterization disposition logic
|
|
WOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', WfrID)
|
|
OrigWOWfrRec = WOWfrRec
|
|
ShipFlag = ShipFlags<0, WaferPos>
|
|
NCRNo = Xlate('WO_WFR', WfrID, 'RDS_NCR_NO', 'X')
|
|
NCRFlag = NCRFlags<0, WaferPos>
|
|
Grade = WOWfrRec<WO_WFR_GRADE$>
|
|
Reason = Reasons<0, WaferPos>
|
|
CharFlag = CharFlags<0, WaferPos>
|
|
DispFlag = DispFlags<0, WaferPos>
|
|
MissingDataValidFlag = ValidationDisFlags<0, WaferPos>
|
|
DataOutOfSpec = OutOfSpecFlags<0, WaferPos>
|
|
DataIsMissing = MissingDataFlags<0, WaferPos>
|
|
InternalFlag = InternalFlags<0, WaferPos>
|
|
ExternalFlag = ExternalFlags<0, WaferPos>
|
|
WfrStatus = WOWfrRec<WO_WFR_STATUS$>
|
|
MetStatus = GaN_Services('GetMetrologyStatus', WfrID)
|
|
CharType = GaN_Services('GetCharType', WfrID)
|
|
WfrIsRunning = GaN_Services('WfrIsRunning', WfrID)
|
|
|
|
If NCRNo NE '' then
|
|
LossCode = Xlate('NCR', NCRNo, 'LOSS_CODE', 'X')
|
|
NCRStatus = Xlate('NCR', NCRNo, 'STATUS', 'X')
|
|
end else
|
|
LossCode = ''
|
|
NCRStatus = ''
|
|
end
|
|
|
|
If ( ( ( (NCRNo NE '') and (LossCode NE 'G24') ) or (ANKO EQ True$) ) and (RDSClosed NE True$) and ( (Grade EQ 'Prod') or (LossCode NE 'G24') ) and (MetStatus EQ True$) ) then
|
|
// Retain the wafer if it hasn't been retained yet (the service checks this).
|
|
Gan_Services('RetainWafer', WfrID)
|
|
end else
|
|
Gan_Services('ClearRetainInfo', WfrID)
|
|
end
|
|
|
|
// Get retain information now in case it has changed by the code block above
|
|
WOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', WfrID)
|
|
RetainBox = WOWfrRec<WO_WFR_RETAIN_BOX$>
|
|
RetainSlot = WOWfrRec<WO_WFR_RETAIN_SLOT$>
|
|
RetainSig = WOWfrRec<WO_WFR_RETAIN_SIG$>
|
|
|
|
If ( (LossCode EQ 'G19') or (LossCode EQ 'G24') ) then
|
|
******** External (G19) or Broken (G24) Characterization Wafer ********
|
|
InternalFlag = False$
|
|
ExternalFlag = (LossCode EQ 'G19')
|
|
Grade = 'Scrap'
|
|
ShipFlag = False$
|
|
If ANKO EQ True$ then
|
|
NCRFlag = False$
|
|
DispFlag = ( (MetStatus EQ True$) and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) )
|
|
end else
|
|
NCRFlag = True$
|
|
DispFlag = ( (MetStatus EQ True$) and (NCRNo NE '') and (NCRStatus EQ 'C') and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) )
|
|
end
|
|
|
|
Begin Case
|
|
Case MetStatus EQ False$
|
|
WfrStatus = 'Metrology is not complete'
|
|
// Move wafer to next scheduled stage
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
NextStageID = Gan_Services('GetNextStage', WfrID)
|
|
NextLocQ = Gan_Services('GetLocQueueID', NextStageID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, NextLocQ)
|
|
Case ( (NCRNo EQ '') and (ANKO NE True$) )
|
|
WfrStatus = 'Wafer has not been NCRed'
|
|
// Move wafer to DISP
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case ( (NCRNo NE '') and (NCRStatus NE 'C') and (ANKO NE True$) )
|
|
WfrStatus = 'NCR has not been closed'
|
|
// Move wafer to DISP
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case ( (DataIsMissing EQ True$) and (MissingDataValidFlag NE True$) )
|
|
WfrStatus = 'Metrology data is missing and data validation has not been disabled'
|
|
// Move wafer to DISP
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case DispFlag EQ True$
|
|
WfrStatus = 'Ready to close'
|
|
// Move wafer to DISP
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
End Case
|
|
|
|
end else
|
|
******** Internal Characterization Wafer ********
|
|
InternalFlag = True$
|
|
ExternalFlag = False$
|
|
NCRFlag = False$
|
|
// Need to look if another wafer has already been characterized.
|
|
Locate WfrID in CharList using @VM setting CharIndex then
|
|
If CharIndex EQ 1 then
|
|
CharReason = 'Internal Characterization (Primary)'
|
|
end else
|
|
CharReason = 'Internal Characterization (Secondary)'
|
|
end
|
|
end else
|
|
CharReason = 'Error'
|
|
end
|
|
Reason = CharReason
|
|
|
|
If ( (CharType EQ 'Light') and (NCRNo EQ '') and ( (DataOutOfSpec EQ False$) or (MissingDataValidFlag EQ True$) ) ) then
|
|
Grade = 'Prod'
|
|
If ANKO EQ True$ then
|
|
ShipFlag = False$
|
|
end else
|
|
ShipFlag = True$
|
|
end
|
|
DispFlag = ( ( (MetStatus EQ True$) and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) and ( (NCRNo EQ '') or ( (NCRNo NE '') and (NCRStatus EQ 'C') and (RetainBox NE '') and (RetainSlot NE '') and (RetainSig NE '') ) ) ) )
|
|
end else
|
|
// Full characterization or metrology failure
|
|
Grade = 'Scrap'
|
|
ShipFlag = False$
|
|
DispFlag = ( (MetStatus EQ True$) and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) )
|
|
end
|
|
|
|
Begin Case
|
|
Case WfrIsRunning EQ True$
|
|
// Move wafer to the tool queue it is running on
|
|
ToolID = GaN_Services('GetWfrRunTool', WfrID)
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
GaN_Services('MoveWfrToQueue', WfrID, ToolID)
|
|
Case MetStatus EQ False$
|
|
WfrStatus = 'Metrology is not complete'
|
|
// Move wafer to next scheduled stage
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
NextStageID = Gan_Services('GetNextStage', WfrID)
|
|
NextLocQ = Gan_Services('GetLocQueueID', NextStageID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, NextLocQ)
|
|
Case ( ( (RetainBox NE '') or (RetainSlot NE '') ) and (RetainSig EQ '') )
|
|
WfrStatus = 'Wafer has not yet been retained'
|
|
// Move wafer to RETAIN queue if it isn't already there.
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
RetainQ = Gan_Services('GetLocQueueID', 'RETAIN')
|
|
Gan_Services('MoveWfrToQueue', WfrID, RetainQ)
|
|
Case ( (NCRNo NE '') and (NCRStatus NE 'C') and (CharType EQ 'Light') )
|
|
WfrStatus = 'NCR has not been closed'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case ( (DataIsMissing EQ True$) and (MissingDataValidFlag NE True$) )
|
|
WfrStatus = 'Metrology data is missing and data validation has not been disabled'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case DispFlag EQ True$
|
|
WfrStatus = 'Ready to close'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
End Case
|
|
|
|
end
|
|
|
|
NCRFlags<0, WaferPos> = NCRFlag
|
|
Reasons<0, WaferPos> = Reason
|
|
DispFlags<0, WaferPos> = DispFlag
|
|
ShipFlags<0, WaferPos> = ShipFlag
|
|
InternalFlags<0, WaferPos> = InternalFlag
|
|
ExternalFlags<0, WaferPos> = ExternalFlag
|
|
|
|
ReactRunRec<REACT_RUN_NCR_REQ$> = NCRFlags
|
|
ReactRunRec<REACT_RUN_DISP_REASON$> = Reasons
|
|
ReactRunRec<REACT_RUN_WFRS_DISP_READY$> = DispFlags
|
|
ReactRunRec<REACT_RUN_CARR_WFR_SHIP$> = ShipFlags
|
|
ReactRunRec<REACT_RUN_INTERNAL$> = InternalFlags
|
|
ReactRunRec<REACT_RUN_EXTERNAL$> = ExternalFlags
|
|
|
|
WOWfrRec<WO_WFR_GRADE$> = Grade
|
|
WOWfrRec<WO_WFR_RETAIN_BOX$> = RetainBox
|
|
WOWfrRec<WO_WFR_RETAIN_SLOT$> = RetainSlot
|
|
WOWfrRec<WO_WFR_STATUS$> = WfrStatus
|
|
|
|
If (WOWfrRec NE OrigWOWfrRec) then
|
|
Database_Services('WriteDataRow', 'WO_WFR', WfrID, WOWfrRec, True$, False$, True$)
|
|
end
|
|
|
|
end else
|
|
|
|
// Non-characterization disposition logic
|
|
WOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', WfrID)
|
|
OrigWOWfrRec = WOWfrRec
|
|
ShipFlag = ShipFlags<0, WaferPos>
|
|
NCRNo = WOWfrRec<WO_WFR_RDS_NCR_NO$>
|
|
NCRFlag = NCRFlags<0, WaferPos>
|
|
CharFlag = CharFlags<0, WaferPos>
|
|
DispFlag = DispFlags<0, WaferPos>
|
|
Grade = WOWfrRec<WO_WFR_GRADE$>
|
|
Reason = Reasons<0, WaferPos>
|
|
MissingDataValidFlag = ValidationDisFlags<0, WaferPos>
|
|
DataOutOfSpec = OutOfSpecFlags<0, WaferPos>
|
|
DataIsMissing = MissingDataFlags<0, WaferPos>
|
|
WfrStatus = WOWfrRec<WO_WFR_STATUS$>
|
|
CriticalFailFlag = WOWfrRec<WO_WFR_CRITICAL_FAILURE$>
|
|
DispStatus = GaN_Services('GetDispStatus', WfrID)
|
|
|
|
If NCRNo NE '' then
|
|
LossCode = Xlate('NCR', NCRNo, 'LOSS_CODE', 'X')
|
|
NCRStatus = Xlate('NCR', NCRNo, 'STATUS', 'X')
|
|
end else
|
|
LossCode = ''
|
|
NCRStatus = ''
|
|
end
|
|
|
|
// Internal Flag - Non-characterized wafers never considered "Internal"
|
|
InternalFlag = False$
|
|
ExternalFlag = (LossCode EQ 'G19')
|
|
|
|
If ( ( ( (NCRNo NE '') and (LossCode NE 'G24') ) or (ANKO EQ True$) ) and (RDSClosed NE True$) and (CriticalFailFlag NE True$) and (DispStatus EQ True$) ) then
|
|
// Retain the wafer if it hasn't been retained yet (the service checks this).
|
|
Gan_Services('RetainWafer', WfrID)
|
|
end else
|
|
Gan_Services('ClearRetainInfo', WfrID)
|
|
end
|
|
|
|
// Get retain information now in case it has changed by the code block above
|
|
WOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', WfrID)
|
|
RetainBox = WOWfrRec<WO_WFR_RETAIN_BOX$>
|
|
RetainSlot = WOWfrRec<WO_WFR_RETAIN_SLOT$>
|
|
RetainSig = WOWfrRec<WO_WFR_RETAIN_SIG$>
|
|
|
|
Begin Case
|
|
|
|
Case CriticalFailFlag EQ True$
|
|
// Bow and/or warp critical limit exceeded, so the wafer must be
|
|
// destroyed to prevent damage to candela tools
|
|
Grade = 'Scrap'
|
|
NCRFlag = True$
|
|
ShipFlag = False$
|
|
DispFlag = ( (NCRNo NE '') and (NCRStatus EQ 'C') )
|
|
Reason = 'Bow and/or warp critical limit exceeded'
|
|
Begin Case
|
|
Case ( (NCRNo NE '') and (NCRStatus EQ 'C') )
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Ready to close'
|
|
Case ( (NCRNo NE '') and (NCRStatus NE 'C') )
|
|
WOWfrRec<WO_WFR_STATUS$> = 'NCR must be closed'
|
|
Case NCRNo EQ ''
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Wafer requires an NCR'
|
|
End Case
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
|
|
Case ( (LossCode EQ 'G19') or (LossCode EQ 'G24') )
|
|
******** External (G19) or Broken (G24) Wafer ********
|
|
Grade = 'Scrap'
|
|
Reason = '' ; // In this case the reason will come from the NCR instead
|
|
If ANKO EQ True$ then
|
|
NCRFlag = False$
|
|
DispFlag = ( (DispStatus EQ True$) and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) and ( (RetainBox NE '') and (RetainSlot NE '') and (RetainSig NE '') ) )
|
|
end else
|
|
NCRFlag = True$
|
|
DispFlag = ( (DispStatus EQ True$) and (NCRNo NE '') and (NCRStatus EQ 'C') and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) and ( (RetainBox EQ '') or (RetainSig NE '') ) )
|
|
end
|
|
ShipFlag = False$
|
|
|
|
Begin Case
|
|
Case DispStatus EQ False$
|
|
WfrStatus = 'Metrology is not complete'
|
|
// Move wafer to next scheduled stage
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
NextStageID = Gan_Services('GetNextStage', WfrID)
|
|
NextLocQ = Gan_Services('GetLocQueueID', NextStageID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, NextLocQ)
|
|
Case ( ( (RetainBox NE '') or (RetainSlot NE '') ) and (RetainSig EQ '') )
|
|
WfrStatus = 'Wafer has not yet been retained'
|
|
// Move wafer to RETAIN queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
RetainQ = Gan_Services('GetLocQueueID', 'RETAIN')
|
|
Gan_Services('MoveWfrToQueue', WfrID, RetainQ)
|
|
Case ( (NCRNo EQ '') and (ANKO NE True$) )
|
|
WfrStatus = 'Wafer has not been NCRed'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case ( (NCRNo NE '') and (NCRStatus NE 'C') and (ANKO NE True$) )
|
|
WfrStatus = 'NCR has not been closed'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case ( (DataIsMissing EQ True$) and (MissingDataValidFlag NE True$) )
|
|
WfrStatus = 'Metrology data is missing and data validation has not been disabled'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case DispFlag EQ True$
|
|
WfrStatus = 'Ready to close'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
End Case
|
|
|
|
Case ScrapRDS EQ True$
|
|
// A characterized wafer has failed, so the entire lot must be scrapped
|
|
If ANKO EQ True$ then
|
|
NCRFlag = False$
|
|
DispFlag = ( (DispStatus EQ True$) and ( (RetainBox NE '') and (RetainSlot NE '') and (RetainSig NE '') and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) ) )
|
|
end else
|
|
NCRFlag = True$
|
|
DispFlag = ( (DispStatus EQ True$) and (NCRNo NE '') and (NCRStatus EQ 'C') and ( (RetainBox NE '') and (RetainSlot NE '') and (RetainSig NE '') and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) ) )
|
|
end
|
|
Grade = 'Scrap'
|
|
Reason = 'Characterization Failure - OOS'
|
|
// Scrapped lots are not eligible to ship
|
|
ShipFlag = False$
|
|
|
|
Begin Case
|
|
Case DispStatus EQ False$
|
|
WfrStatus = 'Disposition stage is not complete'
|
|
// Move wafer to next scheduled stage
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
NextStageID = Gan_Services('GetNextStage', WfrID)
|
|
NextLocQ = Gan_Services('GetLocQueueID', NextStageID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, NextLocQ)
|
|
Case ( ( (RetainBox NE '') or (RetainSlot NE '') ) and (RetainSig EQ '') )
|
|
WfrStatus = 'Wafer has not yet been retained'
|
|
// Move wafer to RETAIN queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
RetainQ = Gan_Services('GetLocQueueID', 'RETAIN')
|
|
Gan_Services('MoveWfrToQueue', WfrID, RetainQ)
|
|
Case ( (NCRNo EQ '') and (ANKO NE True$) )
|
|
WfrStatus = 'Wafer has not been NCRed'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case ( (NCRNo NE '') and (NCRStatus NE 'C') and (ANKO NE True$) )
|
|
WfrStatus = 'NCR has not been closed'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case ( (DataIsMissing EQ True$) and (MissingDataValidFlag NE True$) )
|
|
WfrStatus = 'Metrology data is missing and data validation has not been disabled'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case DispFlag EQ True$
|
|
WfrStatus = 'Ready to close'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
End Case
|
|
|
|
Case DataOutOfSpec EQ True$
|
|
// Data out of spec and the RDS has not been scrapped due to characterization failure
|
|
If ANKO EQ True$ then
|
|
NCRFlag = False$
|
|
DispFlag = ( (DispStatus EQ True$) and (RetainBox NE '') and (RetainSlot NE '') and (RetainSig NE '') and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) )
|
|
end else
|
|
NCRFlag = True$
|
|
DispFlag = ( (DispStatus EQ True$) and (NCRNo NE '') and (NCRStatus EQ 'C') and (RetainBox NE '') and (RetainSlot NE '') and (RetainSig NE '') and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) )
|
|
end
|
|
Grade = 'Scrap'
|
|
Reason = 'Metrology Failure - OOS'
|
|
// Failed wafers are never eligible to ship
|
|
ShipFlag = False$
|
|
|
|
Begin Case
|
|
Case DispStatus EQ False$
|
|
WfrStatus = 'Disposition stage is not complete'
|
|
// Move wafer to next scheduled stage
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
NextStageID = Gan_Services('GetNextStage', WfrID)
|
|
NextLocQ = Gan_Services('GetLocQueueID', NextStageID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, NextLocQ)
|
|
Case ( ( (RetainBox NE '') or (RetainSlot NE '') ) and (RetainSig EQ '') )
|
|
WfrStatus = 'Wafer has not yet been retained'
|
|
// Move wafer to RETAIN queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
RetainQ = Gan_Services('GetLocQueueID', 'RETAIN')
|
|
Gan_Services('MoveWfrToQueue', WfrID, RetainQ)
|
|
Case ( (NCRNo EQ '') and (ANKO NE True$) )
|
|
WfrStatus = 'Wafer has not been NCRed'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case ( (NCRNo NE '') and (NCRStatus NE 'C') and (ANKO NE True$) )
|
|
WfrStatus = 'NCR has not been closed'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case ( (DataIsMissing EQ True$) and (MissingDataValidFlag NE True$) )
|
|
WfrStatus = 'Metrology data is missing and data validation has not been disabled'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case DispFlag EQ True$
|
|
WfrStatus = 'Ready to close'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
End Case
|
|
|
|
Case ( (DataOutOfSpec EQ False$) and (NCRNo NE '') )
|
|
// Data within spec, but wafer manually NCRd
|
|
Grade = 'Scrap'
|
|
Reason = 'NCR'
|
|
NCRStatus = Xlate('NCR', NCRNo, 'STATUS', 'X')
|
|
DispFlag = ( (NCRStatus EQ 'C') and (RetainBox NE '') and (RetainSlot NE '') and (RetainSig NE '') and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) )
|
|
// NCRd wafers are never eligible to ship
|
|
ShipFlag = False$
|
|
|
|
Begin Case
|
|
Case ( ( (RetainBox NE '') or (RetainSlot NE '') ) and (RetainSig EQ '') )
|
|
WfrStatus = 'Wafer has not yet been retained'
|
|
// Move wafer to RETAIN queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
RetainQ = Gan_Services('GetLocQueueID', 'RETAIN')
|
|
Gan_Services('MoveWfrToQueue', WfrID, RetainQ)
|
|
Case NCRStatus NE 'C'
|
|
WfrStatus = 'NCR has not been closed'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case ( (DataIsMissing EQ True$) and (MissingDataValidFlag NE True$) )
|
|
WfrStatus = 'Metrology data is missing and data validation has not been disabled'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case DispFlag EQ True$
|
|
WfrStatus = 'Ready to close'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
End Case
|
|
|
|
Case DataOutOfSpec EQ False$
|
|
// Data within spec and the RDS has not been scrapped due to characterization failure
|
|
NCRFlag = False$
|
|
If DispStatus EQ True$ then
|
|
Grade = 'Prod'
|
|
end else
|
|
Grade = ''
|
|
end
|
|
Reason = ''
|
|
If ANKO EQ True$ then
|
|
DispFlag = ( (DispStatus EQ True$) and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) and ( (RetainBox NE '') and (RetainSlot NE '') and (RetainSig NE '') ) )
|
|
ShipFlag = False$
|
|
end else
|
|
DispFlag = ( (DispStatus EQ True$) and ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) ) and ( (RetainBox EQ '') or (RetainSig NE '') ) )
|
|
ShipFlag = ( (DataIsMissing EQ False$) or (MissingDataValidFlag EQ True$) )
|
|
end
|
|
|
|
Begin Case
|
|
Case DispStatus EQ False$
|
|
WfrStatus = 'Disposition stage is not complete'
|
|
// Move wafer to next scheduled stage
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
NextStageID = Gan_Services('GetNextStage', WfrID)
|
|
NextLocQ = Gan_Services('GetLocQueueID', NextStageID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, NextLocQ)
|
|
Case ( ( (RetainBox NE '') or (RetainSlot NE '') ) and (RetainSig EQ '') )
|
|
WfrStatus = 'Wafer has not yet been retained'
|
|
// Move wafer to RETAIN queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
RetainQ = Gan_Services('GetLocQueueID', 'RETAIN')
|
|
Gan_Services('MoveWfrToQueue', WfrID, RetainQ)
|
|
Case ( (DataIsMissing EQ True$) and (MissingDataValidFlag NE True$) )
|
|
WfrStatus = 'Metrology data is missing and data validation has not been disabled'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
Case DispFlag EQ True$
|
|
WfrStatus = 'Ready to close'
|
|
// Move wafer to DISP queue
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
DispQ = Gan_Services('GetLocQueueID', 'DISP')
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
End Case
|
|
|
|
End Case
|
|
|
|
NCRFlags<0, WaferPos> = NCRFlag
|
|
Reasons<0, WaferPos> = Reason
|
|
DispFlags<0, WaferPos> = DispFlag
|
|
ShipFlags<0, WaferPos> = ShipFlag
|
|
InternalFlags<0, WaferPos> = InternalFlag
|
|
ExternalFlags<0, WaferPos> = ExternalFlag
|
|
|
|
ReactRunRec<REACT_RUN_NCR_REQ$> = NCRFlags
|
|
ReactRunRec<REACT_RUN_DISP_REASON$> = Reasons
|
|
ReactRunRec<REACT_RUN_WFRS_DISP_READY$> = DispFlags
|
|
ReactRunRec<REACT_RUN_CARR_WFR_SHIP$> = ShipFlags
|
|
ReactRunRec<REACT_RUN_INTERNAL$> = InternalFlags
|
|
ReactRunRec<REACT_RUN_EXTERNAL$> = ExternalFlags
|
|
|
|
WOWfrRec<WO_WFR_GRADE$> = Grade
|
|
WOWfrRec<WO_WFR_RETAIN_BOX$> = RetainBox
|
|
WOWfrRec<WO_WFR_RETAIN_SLOT$> = RetainSlot
|
|
WOWfrRec<WO_WFR_STATUS$> = WfrStatus
|
|
|
|
If (WOWfrRec NE OrigWOWfrRec) then
|
|
Database_Services('WriteDataRow', 'WO_WFR', WfrID, WOWfrRec, True$, False$, True$)
|
|
end
|
|
end
|
|
end
|
|
|
|
If ReactRunRec NE OrigReactRunRec then
|
|
Database_Services('WriteDataRow', 'REACT_RUN', RDSNo, ReactRunRec, True$, False$, True$)
|
|
end
|
|
|
|
Case TechType EQ 'E'
|
|
|
|
// Engineering Run
|
|
CurrDTM = DateTime()
|
|
ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo)
|
|
OrigReactRunRec = ReactRunRec
|
|
InWfrIDs = ReactRunRec<REACT_RUN_IN_WFR_ID$>
|
|
ShipFlags = ReactRunRec<REACT_RUN_CARR_WFR_SHIP$>
|
|
RetainFlags = ReactRunRec<REACT_RUN_GAN_RET_WFR$>
|
|
InternalFlags = ReactRunRec<REACT_RUN_INTERNAL$>
|
|
ExternalFlags = ReactRunRec<REACT_RUN_EXTERNAL$>
|
|
CassDispComp = ReactRunRec<REACT_RUN_DISP_COMPLETE$>
|
|
WfrsDispReady = ReactRunRec<REACT_RUN_WFRS_DISP_READY$>
|
|
NCRReqFlags = ReactRunRec<REACT_RUN_NCR_REQ$>
|
|
CharFlags = ReactRunRec<REACT_RUN_IN_WFR_CHAR$>
|
|
|
|
Locate WfrID in InWfrIDs using @VM setting WfrIndex then
|
|
WOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', WfrID)
|
|
OrigWOWfrRec = WOWfrRec
|
|
ShipFlag = ShipFlags<0, WfrIndex>
|
|
RetainFlag = RetainFlags<0, WfrIndex>
|
|
InternalFlag = InternalFlags<0, WfrIndex>
|
|
ExternalFlag = ExternalFlags<0, WfrIndex>
|
|
CharFlag = CharFlags<0, WfrIndex>
|
|
DispReady = WfrsDispReady<0, WfrIndex>
|
|
NCRNo = WOWfrRec<WO_WFR_RDS_NCR_NO$>
|
|
NCRStatus = Xlate('NCR', NCRNo, 'STATUS', 'X')
|
|
CriticalFailFlag = WOWfrRec<WO_WFR_CRITICAL_FAILURE$>
|
|
NCRReq = NCRReqFlags<0, WfrIndex>
|
|
DestStatus = GaN_Services('GetDestroyedStatus', WfrID)
|
|
If ( (CharFlag EQ 'DUMMY') or (CharFlag EQ 'EMPTY') ) then
|
|
DispReady = True$
|
|
WfrsDispReady<0, WfrIndex> = DispReady
|
|
ReactRunRec<REACT_RUN_WFRS_DISP_READY$> = WfrsDispReady
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Ready to close'
|
|
end
|
|
If DestStatus EQ True$ then
|
|
If ( (InternalFlag NE True$) and (ExternalFlag NE True$) ) then
|
|
// Mark wafer's internal flag. Clear all other flags.
|
|
ShipFlag = False$
|
|
RetainFlag = False$
|
|
InternalFlag = True$
|
|
ExternalFlag = False$
|
|
ShipFlags<0, WfrIndex> = ShipFlag
|
|
RetainFlags<0, WfrIndex> = RetainFlag
|
|
InternalFlags<0, WfrIndex> = InternalFlag
|
|
ExternalFlags<0, WfrIndex> = ExternalFlag
|
|
ReactRunRec<REACT_RUN_CARR_WFR_SHIP$> = ShipFlags
|
|
ReactRunRec<REACT_RUN_GAN_RET_WFR$> = RetainFlags
|
|
ReactRunRec<REACT_RUN_INTERNAL$> = InternalFlags
|
|
ReactRunRec<REACT_RUN_EXTERNAL$> = ExternalFlags
|
|
end
|
|
end else
|
|
// Wafer may have been previously marked as external or internal. Since the destroyed status
|
|
// is now false clear internal and external flag.
|
|
InternalFlag = False$
|
|
ExternalFlag = False$
|
|
InternalFlags<0, WfrIndex> = InternalFlag
|
|
ExternalFlags<0, WfrIndex> = ExternalFlag
|
|
ReactRunRec<REACT_RUN_INTERNAL$> = InternalFlags
|
|
ReactRunRec<REACT_RUN_EXTERNAL$> = ExternalFlags
|
|
end
|
|
|
|
MetStatus = GaN_Services('GetMetrologyStatus', WfrID)
|
|
DispStatus = GaN_Services('GetDispStatus', WfrID)
|
|
|
|
Begin Case
|
|
Case CriticalFailFlag EQ True$
|
|
// Bow and/or warp critical limit exceeded, so the wafer must be
|
|
// destroyed to prevent damage to candela tools
|
|
Reason = 'Bow and/or warp critical limit exceeded'
|
|
Begin Case
|
|
Case ( (NCRNo NE '') and (NCRStatus EQ 'C') )
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Ready to close'
|
|
Case ( (NCRNo NE '') and (NCRStatus NE 'C') )
|
|
WOWfrRec<WO_WFR_STATUS$> = 'NCR must be closed'
|
|
Case NCRNo EQ ''
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Wafer requires an NCR'
|
|
End Case
|
|
DispReady = ( (NCRNo NE '') and (NCRStatus EQ 'C') )
|
|
WfrsDispReady<0, WfrIndex> = DispReady
|
|
ReactRunRec<REACT_RUN_WFRS_DISP_READY$> = WfrsDispReady
|
|
|
|
Case ( (MetStatus EQ True$) or (DispStatus EQ True$) )
|
|
// Check Ship, Interal, External, and Retain conditions to determine if wafer should be removed from the WIP
|
|
FormattedWfrID = WfrID
|
|
Convert '*' to '.' in FormattedWfrID
|
|
Begin Case
|
|
Case ShipFlag EQ True$
|
|
GPackQ = GaN_Services('GetLocQueueID', 'G_PACK')
|
|
ShipID = ReactRunRec<REACT_RUN_OUT_SLOT_ID$, WfrIndex>
|
|
RunStageWfrKey = RDSNo:'*DISP*':FormattedWfrID
|
|
RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey)
|
|
StageStatus = RunStageWfrRec<RUN_STAGE_WFR_STATUS$>
|
|
If StageStatus _EQC 'INIT' then
|
|
// Mark DISP stage as complete
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_BY$> = @USER4
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_DTM$> = CurrDTM
|
|
RunStageWfrRec<RUN_STAGE_WFR_STATUS$> = 'COMP'
|
|
Database_Services('WriteDataRow', 'RUN_STAGE_WFR', RunStageWfrKey, RunStageWfrRec, True$, False$, True$)
|
|
end
|
|
Begin Case
|
|
Case (ShipID EQ '')
|
|
LocQ = GaN_Services('GetWfrQueue', WfrID)
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Wafer needs to be placed in an outbound cassette'
|
|
If LocQ _EQC GPackQ then
|
|
// Wafer is being removed from an outbound cassette, so place the wafer back into the G_PACK
|
|
// queue and reset the G_PACK RUN_STAGE_WFR record to 'INIT'.
|
|
RunStageWfrKey = RDSNo:'*G_PACK*':FormattedWfrID
|
|
RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey)
|
|
StageStatus = RunStageWfrRec<RUN_STAGE_WFR_STATUS$>
|
|
If StageStatus _EQC 'COMP' then
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_BY$> = ''
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_DTM$> = ''
|
|
RunStageWfrRec<RUN_STAGE_WFR_STATUS$> = 'INIT'
|
|
Database_Services('WriteDataRow', 'RUN_STAGE_WFR', RunStageWfrKey, RunStageWfrRec, True$, False$, True$)
|
|
Gan_Services('MoveWfrToQueue', WfrID, GPackQ)
|
|
end
|
|
end else
|
|
// Wafer has been marked as shipped in the Disposition Report (Excel spreadsheet), but has
|
|
// not yet been added to an outbound cassette. Remove the wafer from its current location
|
|
// (which likely is DISP), then place the wafer in the G_PACK location queue and update
|
|
// the wafer trace (WO_WFR record).
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, GPackQ)
|
|
// Update wafer trace (WO_WFR record)
|
|
LocDTM = WOWfrRec<WO_WFR_LOC_DTM$>
|
|
NextPos = DCount(LocDTM, @VM) + 1
|
|
WOWfrRec<WO_WFR_LOC_DTM$, NextPos> = CurrDTM
|
|
WOWfrRec<WO_WFR_LOC_BY$, NextPos> = @USER4
|
|
WOWfrRec<WO_WFR_LOC_EVENT$, NextPos> = 'COMP'
|
|
WOWfrRec<WO_WFR_TOOL_ID$, NextPos> = ''
|
|
WOWfrRec<WO_WFR_INV_LOC$, NextPos> = GPackQ
|
|
end
|
|
Case ( (ShipID NE '') and ( (CassDispComp EQ False$) or (CassDispComp EQ '') ) )
|
|
// Wafer is ready for disposition, so mark it as such. Once user marks the cassette
|
|
// disposition complete, then the wafer will move off the WIP. Move wafer to the G_PACK
|
|
// location queue if it is not there and update the wafer trace (WO_WFR record).
|
|
If (NCRReq EQ False$) or ( (NCRReq EQ True$) and (NCRNo NE '') ) then
|
|
LocQ = Gan_Services('GetWfrQueue', WfrID)
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, GPackQ)
|
|
// Update wafer trace (WO_WFR record)
|
|
LocDTM = WOWfrRec<WO_WFR_LOC_DTM$>
|
|
NextPos = DCount(LocDTM, @VM) + 1
|
|
WOWfrRec<WO_WFR_LOC_DTM$, NextPos> = CurrDTM
|
|
WOWfrRec<WO_WFR_LOC_BY$, NextPos> = @USER4
|
|
WOWfrRec<WO_WFR_LOC_EVENT$, NextPos> = 'G_PACK'
|
|
WOWfrRec<WO_WFR_TOOL_ID$, NextPos> = ''
|
|
WOWfrRec<WO_WFR_INV_LOC$, NextPos> = GPackQ
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Ready to close'
|
|
DispReady = True$
|
|
WfrsDispReady<0, WfrIndex> = DispReady
|
|
ReactRunRec<REACT_RUN_WFRS_DISP_READY$> = WfrsDispReady
|
|
end
|
|
Case ( (ShipID NE '') and (CassDispComp EQ True$) )
|
|
// A ship ID has been added (i.e. the wafer has been placed in an outbound cassette and the
|
|
// user has marked the cassette disposition as complete, so remove the wafer from the
|
|
// GaN WIP and mark the G_PACK stage as complete.)
|
|
RunStageWfrKey = RDSNo:'*G_PACK*':FormattedWfrID
|
|
RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey)
|
|
StageStatus = RunStageWfrRec<RUN_STAGE_WFR_STATUS$>
|
|
LocQ = Gan_Services('GetWfrQueue', WfrID)
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Run closed'
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
If StageStatus _EQC 'INIT' then
|
|
// Mark G_PACK stage as complete
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_BY$> = @USER4
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_DTM$> = CurrDTM
|
|
RunStageWfrRec<RUN_STAGE_WFR_STATUS$> = 'COMP'
|
|
Database_Services('WriteDataRow', 'RUN_STAGE_WFR', RunStageWfrKey, RunStageWfrRec, True$, False$, True$)
|
|
end
|
|
Case Otherwise$
|
|
// No action necessary at this time.
|
|
Null
|
|
End Case
|
|
|
|
Case RetainFlag EQ True$
|
|
|
|
RetainSlot = WOWfrRec<WO_WFR_RETAIN_SLOT$>
|
|
RetainBox = WOWfrRec<WO_WFR_RETAIN_BOX$>
|
|
RetainSig = WOWfrRec<WO_WFR_RETAIN_SIG$>
|
|
RetainQ = GaN_Services('GetLocQueueID', 'RETAIN')
|
|
RunStageWfrKey = RDSNo:'*DISP*':FormattedWfrID
|
|
RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey)
|
|
StageStatus = RunStageWfrRec<RUN_STAGE_WFR_STATUS$>
|
|
If StageStatus _EQC 'INIT' then
|
|
// Retain flag has been set and metrology is complete, so mark DISP stage as complete.
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_BY$> = @User4
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_DTM$> = CurrDTM
|
|
RunStageWfrRec<RUN_STAGE_WFR_STATUS$> = 'COMP'
|
|
Database_Services('WriteDataRow', 'RUN_STAGE_WFR', RunStageWfrKey, RunStageWfrRec, True$, False$, True$)
|
|
end
|
|
Begin Case
|
|
|
|
Case ( (RetainSlot EQ '') or (RetainBox EQ '') )
|
|
// Wafer needs to go into RETAIN queue until it receives a Retain Slot and Retain Box
|
|
// If wafer is not at RETAIN, then update wafer trace (WO_WFR record) and move the wafer.
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Wafer requires a retain box and retain slot'
|
|
CurrStage = GaN_Services('GetCurrStage', WfrID)
|
|
LocQ = GaN_Services('GetWfrQueue', WfrID)
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, RetainQ)
|
|
If CurrStage NE 'RETAIN' then
|
|
LocDTM = WOWfrRec<WO_WFR_LOC_DTM$>
|
|
NextPos = DCount(LocDTM, @VM) + 1
|
|
WOWfrRec<WO_WFR_LOC_DTM$, NextPos> = CurrDTM
|
|
WOWfrRec<WO_WFR_LOC_BY$, NextPos> = @USER4
|
|
WOWfrRec<WO_WFR_LOC_EVENT$, NextPos> = 'COMP'
|
|
WOWfrRec<WO_WFR_TOOL_ID$, NextPos> = ''
|
|
WOWfrRec<WO_WFR_INV_LOC$, NextPos> = RetainQ
|
|
end
|
|
Case ( (RetainSlot NE '') and (RetainBox NE '') and (CassDispComp NE True$) )
|
|
// Wafer is ready for disposition, so mark it as such. Once user marks the cassette
|
|
// disposition complete, then the wafer will move off the WIP. Move wafer into RETAIN stage
|
|
// if it is not currently there. This can occur if an RDS is opened after being closed.
|
|
If ( ( (NCRReq EQ False$) or ( (NCRReq EQ True$) and (NCRNo NE '') ) ) and (RetainSig NE '') ) then
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Ready to close'
|
|
DispReady = True$
|
|
end else
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Wafer has not yet been retained'
|
|
DispReady = False$
|
|
end
|
|
RetainQ = 'GCH*Q_RETAIN'
|
|
LocQ = Gan_Services('GetWfrQueue', WfrID)
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, RetainQ)
|
|
LocDTM = WOWfrRec<WO_WFR_LOC_DTM$>
|
|
NextPos = DCount(LocDTM, @VM) + 1
|
|
WOWfrRec<WO_WFR_LOC_DTM$, NextPos> = CurrDTM
|
|
WOWfrRec<WO_WFR_LOC_BY$, NextPos> = @USER4
|
|
WOWfrRec<WO_WFR_LOC_EVENT$, NextPos> = 'RETAIN'
|
|
WOWfrRec<WO_WFR_TOOL_ID$, NextPos> = ''
|
|
WOWfrRec<WO_WFR_INV_LOC$, NextPos> = RetainQ
|
|
WfrsDispReady<0, WfrIndex> = DispReady
|
|
ReactRunRec<REACT_RUN_WFRS_DISP_READY$> = WfrsDispReady
|
|
Case ( ( (RetainSlot NE '') and (RetainBox NE '') and (RetainSig NE '') ) and (CassDispComp EQ True$) )
|
|
// Retain slot and retain box are populated and the user has marked disposition complete ->
|
|
// mark RETAIN stage complete and remove the wafer from the GaN WIP.
|
|
RunStageWfrKey = RDSNo:'*RETAIN*':FormattedWfrID
|
|
RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey)
|
|
StageStatus = RunStageWfrRec<RUN_STAGE_WFR_STATUS$>
|
|
LocQ = Gan_Services('GetWfrQueue', WfrID)
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Run closed'
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
If StageStatus _EQC 'INIT' then
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_BY$> = @User4
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_DTM$> = CurrDTM
|
|
RunStageWfrRec<RUN_STAGE_WFR_STATUS$> = 'COMP'
|
|
Database_Services('WriteDataRow', 'RUN_STAGE_WFR', RunStageWfrKey, RunStageWfrRec, True$, False$, True$)
|
|
end
|
|
Case Otherwise$
|
|
// No action necessary at this time.
|
|
Null
|
|
|
|
End Case
|
|
|
|
Case InternalFlag EQ True$
|
|
Begin Case
|
|
Case ( (CassDispComp EQ False$) or (CassDispComp EQ '') )
|
|
// Wafer is ready for disposition, so mark it as such. Once user marks the cassette
|
|
// disposition complete, then the wafer will move off the WIP.
|
|
DispReady = True$
|
|
WfrsDispReady<0, WfrIndex> = DispReady
|
|
ReactRunRec<REACT_RUN_WFRS_DISP_READY$> = WfrsDispReady
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Ready to close'
|
|
Case CassDispComp EQ True$
|
|
// Remove the wafer from the GaN WIP and mark DISP stage as complete.
|
|
RunStageWfrKey = RDSNo:'*DISP*':FormattedWfrID
|
|
RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey)
|
|
StageStatus = RunStageWfrRec<RUN_STAGE_WFR_STATUS$>
|
|
LocQ = GaN_Services('GetWfrQueue', WfrID)
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Run closed'
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
If StageStatus _EQC 'INIT' then
|
|
// Mark DISP stage as complete
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_BY$> = @User4
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_DTM$> = CurrDTM
|
|
RunStageWfrRec<RUN_STAGE_WFR_STATUS$> = 'COMP'
|
|
Database_Services('WriteDataRow', 'RUN_STAGE_WFR', RunStageWfrKey, RunStageWfrRec, True$, False$, True$)
|
|
end
|
|
End Case
|
|
|
|
Case ExternalFlag EQ True$
|
|
|
|
Begin Case
|
|
Case ( (CassDispComp EQ False$) or (CassDispComp EQ '') )
|
|
// Check to see if an NCR has been added to this wafer before marking this wafer as ready
|
|
// to be dispositioned.
|
|
If ( (NCRReq EQ False$) or ( (NCRReq EQ True$) and (NCRNo NE '') ) ) then
|
|
// Wafer is ready for disposition, so mark it as such. Once user marks the cassette
|
|
// disposition complete, then the wafer will move off the WIP.
|
|
DispReady = True$
|
|
WfrsDispReady<0, WfrIndex> = DispReady
|
|
ReactRunRec<REACT_RUN_WFRS_DISP_READY$> = WfrsDispReady
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Ready to close'
|
|
end
|
|
Case CassDispComp EQ True$
|
|
// Remove the wafer from the GaN WIP and mark DISP stage as complete.
|
|
RunStageWfrKey = RDSNo:'*DISP*':FormattedWfrID
|
|
RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey)
|
|
StageStatus = RunStageWfrRec<RUN_STAGE_WFR_STATUS$>
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Run closed'
|
|
LocQ = Gan_Services('GetWfrQueue', WfrID)
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
If StageStatus _EQC 'INIT' then
|
|
// Mark DISP stage as complete
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_BY$> = @User4
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_DTM$> = CurrDTM
|
|
RunStageWfrRec<RUN_STAGE_WFR_STATUS$> = 'COMP'
|
|
Database_Services('WriteDataRow', 'RUN_STAGE_WFR', RunStageWfrKey, RunStageWfrRec, True$, False$, True$)
|
|
end
|
|
End Case
|
|
|
|
Case Otherwise$
|
|
// All flags false. Lot aborted or disposition report not found.
|
|
Begin Case
|
|
Case ( (CassDispComp EQ False$) or (CassDispComp EQ '') )
|
|
// Move wafer to DISP queue if it is not there
|
|
DispQ = 'GGR*Q_DISP'
|
|
CurrQ = Gan_Services('GetWfrQueue', WfrID)
|
|
If CurrQ _NEC DispQ then
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, DispQ)
|
|
end
|
|
// Check to see if an NCR has been added to this wafer before marking this wafer as ready
|
|
// to be dispositioned.
|
|
If ( (NCRReq EQ False$) or ( (NCRReq EQ True$) and (NCRNo NE '') ) ) then
|
|
// Wafer is ready for disposition, so mark it as such. Once user marks the cassette
|
|
// disposition complete, then the wafer will move off the WIP.
|
|
DispReady = True$
|
|
WfrsDispReady<0, WfrIndex> = DispReady
|
|
ReactRunRec<REACT_RUN_WFRS_DISP_READY$> = WfrsDispReady
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Ready to close'
|
|
end else
|
|
If NCRReq EQ True$ then
|
|
WOWfrRec<WO_WFR_STATUS$> = 'NCR required'
|
|
end else
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Disposition report not found'
|
|
end
|
|
end
|
|
Case CassDispComp EQ True$
|
|
// Remove the wafer from the GaN WIP and mark DISP stage as complete.
|
|
RunStageWfrKey = RDSNo:'*DISP*':FormattedWfrID
|
|
RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey)
|
|
StageStatus = RunStageWfrRec<RUN_STAGE_WFR_STATUS$>
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Run closed'
|
|
LocQ = GaN_Services('GetWfrQueue', WfrID)
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
If StageStatus _EQC 'INIT' then
|
|
// Mark DISP stage as complete
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_BY$> = @User4
|
|
RunStageWfrRec<RUN_STAGE_WFR_COMP_DTM$> = CurrDTM
|
|
RunStageWfrRec<RUN_STAGE_WFR_STATUS$> = 'COMP'
|
|
Database_Services('WriteDataRow', 'RUN_STAGE_WFR', RunStageWfrKey, RunStageWfrRec, True$, False$, True$)
|
|
end
|
|
End Case
|
|
End Case
|
|
|
|
Case Otherwise$
|
|
// Metrology or Disposition not complete
|
|
WOWfrRec<WO_WFR_STATUS$> = 'Metrology incomplete'
|
|
WfrIsRunning = GaN_Services('WfrIsRunning', WfrID)
|
|
If WfrIsRunning EQ True$ then
|
|
// Move wafer to the tool queue it is runnig on
|
|
ToolID = GaN_Services('GetWfrRunTool', WfrID)
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
GaN_Services('MoveWfrToQueue', WfrID, ToolID)
|
|
end else
|
|
// Move wafer to next scheduled stage
|
|
Gan_Services('RemoveWfrFromWIP', WfrID)
|
|
NextStageID = Gan_Services('GetNextStage', WfrID)
|
|
NextLocQ = Gan_Services('GetLocQueueID', NextStageID)
|
|
Gan_Services('MoveWfrToQueue', WfrID, NextLocQ)
|
|
end
|
|
|
|
End Case
|
|
If OrigWOWfrRec NE WOWfrRec then Database_Services('WriteDataRow', 'WO_WFR', WfrID, WOWfrRec, True$, False$, True$)
|
|
end
|
|
|
|
If OrigReactRunRec NE ReactRunRec then Database_Services('WriteDataRow', 'REACT_RUN', RDSNo, ReactRunRec, True$, False$, True$)
|
|
|
|
Case Otherwise$
|
|
// Error
|
|
Null
|
|
End Case
|
|
|
|
end service
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Internal GoSubs
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ClearCursors:
|
|
For counter = 0 to 8
|
|
ClearSelect counter
|
|
Next counter
|
|
return
|
|
|