360 lines
16 KiB
Plaintext
360 lines
16 KiB
Plaintext
Function Epi_Part_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 : Epi_Part_Services
|
|
|
|
Description : Handler program for all module related services.
|
|
|
|
Notes : The generic parameters should contain all the necessary information to process the services. Often
|
|
this will be information like the data Record and Key ID.
|
|
|
|
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)
|
|
06/29/17 dmb Original programmer. - [EPIOI-8]
|
|
|
|
***********************************************************************************************************************/
|
|
|
|
#pragma precomp SRP_PreCompiler
|
|
|
|
$insert APP_INSERTS
|
|
$insert SERVICE_SETUP
|
|
$insert WO_LOG_EQUATES
|
|
$insert EPI_PART_EQUATES
|
|
$insert PROD_VER_EQUATES
|
|
$insert PROD_SPEC_EQUATES
|
|
$insert RLIST_EQUATES
|
|
|
|
Declare subroutine Error_Services, Epi_Part_Services, Memory_Services, RList, Database_Services
|
|
Declare function SRP_Array, Epi_Part_Services, Memory_Services, Database_Services, SRP_Sort_Array
|
|
|
|
GoToService else
|
|
Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.')
|
|
end
|
|
|
|
Return Response else ''
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Service Parameter Options
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Options REACTORTYPES = 'ASM', 'ASM+', 'HTR', 'EpiPro', 'GaN'
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Services
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// SetReactorUtilization
|
|
//
|
|
// Sets the utilization constant for the indicated reactor type.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service SetReactorUtilization(ReactorType=REACTORTYPES, ReactorUtilization)
|
|
|
|
Convert @Lower_Case to @Upper_Case in ReactorType
|
|
|
|
If ReactorType NE '' AND ReactorUtilization NE '' then
|
|
Database_Services('WriteDataRow', 'CONFIG', 'ReactUtil*' : ReactorType, ReactorUtilization, True$)
|
|
If Error_Services('NoError') then
|
|
Memory_Services('SetValue', ServiceModule : '*GetReactorUtilization*' : ReactorType, ReactorUtilization)
|
|
end
|
|
end else
|
|
Error_Services('Add', 'ReactorType or ReactorUtilization argument was missing from the ' : Service : ' service.')
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetReactorUtilization
|
|
//
|
|
// Returns the utilization constant for the indicated reactor type.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetReactorUtilization(ReactorType=REACTORTYPES)
|
|
|
|
Convert @Lower_Case to @Upper_Case in ReactorType
|
|
ServiceKeyID := '*' : ReactorType
|
|
ReactorUtilization = Memory_Services('GetValue', ServiceKeyID)
|
|
|
|
If ReactorUtilization EQ '' then
|
|
If ReactorType NE '' then
|
|
ReactorUtilization = Database_Services('ReadDataRow', 'CONFIG', 'ReactUtil*' : ReactorType)
|
|
If Error_Services('NoError') then
|
|
Memory_Services('SetValue', ServiceKeyID, ReactorUtilization)
|
|
end
|
|
end else
|
|
Error_Services('Add', 'ReactorType argument was missing from the ' : Service : ' service.')
|
|
end
|
|
end
|
|
|
|
Response = ReactorUtilization
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetProdVerNo
|
|
//
|
|
// Returns the minutes per wafer associated to the indicated Epi Part and reactor type.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetProdVerNo(EpiPartNo, ReactorType=REACTORTYPES)
|
|
|
|
Convert @Lower_Case to @Upper_Case in ReactorType
|
|
ServiceKeyID := '*' : EpiPartNo : '*' : ReactorType
|
|
ProdVerNo = Memory_Services('GetValue', ServiceKeyID)
|
|
|
|
If ProdVerNo EQ '' then
|
|
If EpiPartNo NE '' AND ReactorType NE '' then
|
|
EpiPartRec = Database_Services('ReadDataRow', 'EPI_PART', EpiPartNo)
|
|
If Error_Services('NoError') then
|
|
// Convert the friendly reactor type name to the internal one used in the database.
|
|
Begin Case
|
|
Case ReactorType _EQC 'EpiPro' ; ReactorType = 'EPP'
|
|
Case ReactorType _EQC 'ASM' ; ReactorType = 'EPS'
|
|
End Case
|
|
ProdVerNos = EpiPartRec<EPI_PART_PROD_VER_NO$>
|
|
NumProdVers = DCount(ProdVerNos, @VM)
|
|
FoundProdVer = False$
|
|
For ProdVerCnt = NumProdVers to 1 Step -1
|
|
ProdVerNo = ProdVerNos<0, ProdVerCnt>
|
|
ProdVerRec = Database_Services('ReadDataRow', 'PROD_VER', ProdVerNo)
|
|
If Error_Services('NoError') then
|
|
ProdVerReactorType = ProdVerRec<PROD_VER_REACT_TYPE$>
|
|
If ProdVerReactorType _EQC ReactorType then FoundProdVer = True$
|
|
end
|
|
Until FoundProdVer
|
|
Next ProdVerCnt
|
|
If FoundProdVer then
|
|
Memory_Services('SetValue', ServiceKeyID, ProdVerNo)
|
|
end
|
|
end
|
|
end else
|
|
Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.')
|
|
end
|
|
end
|
|
|
|
Response = ProdVerNo
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetMinutesPerWaferCost
|
|
//
|
|
// Returns the minutes per wafer needed for costing associated to the indicated Epi Part and reactor type.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetMinutesPerWaferCost(EpiPartNo, ReactorType=REACTORTYPES)
|
|
|
|
Convert @Lower_Case to @Upper_Case in ReactorType
|
|
ServiceKeyID := '*' : EpiPartNo : '*' : ReactorType
|
|
MinutesPerWafer = Memory_Services('GetValue', ServiceKeyID)
|
|
|
|
If MinutesPerWafer EQ '' then
|
|
If EpiPartNo NE '' AND ReactorType NE '' then
|
|
ProdVerNo = Epi_Part_Services('GetProdVerNo', EpiPartNo, ReactorType)
|
|
If Error_Services('NoError') then
|
|
ProdVerRec = Database_Services('ReadDataRow', 'PROD_VER', ProdVerNo)
|
|
If Error_Services('NoError') then
|
|
ProdSpecNo = ProdVerRec<PROD_VER_PROC_STEP_PSN$>[-1, 'B' : @VM] ; // Always get the last Prod Spec No to use.
|
|
ProdSpecRec = Database_Services('ReadDataRow', 'PROD_SPEC', ProdSpecNo)
|
|
If Error_Services('NoError') then
|
|
MinutesPerWafer = ProdSpecRec<PROD_SPEC_MINUTES_PER_WAFER$>
|
|
MinutesPerWafer = Oconv(MinutesPerWafer, 'MD3')
|
|
Memory_Services('SetValue', ServiceKeyID, MinutesPerWafer)
|
|
end
|
|
end
|
|
end
|
|
end else
|
|
Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.')
|
|
end
|
|
end
|
|
|
|
Response = MinutesPerWafer
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// SetMinutesPerWaferScheduler
|
|
//
|
|
// Sets the minutes per wafer needed for scheduling associated to the indicated Epi Part and reactor type.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service SetMinutesPerWaferScheduler(EpiPartNo, ReactorType=REACTORTYPES, MinutesPerWafer)
|
|
|
|
Convert @Lower_Case to @Upper_Case in ReactorType
|
|
|
|
* If EpiPartNo NE '' AND ReactorType NE '' AND MinutesPerWafer NE '' then
|
|
If EpiPartNo NE '' AND ReactorType NE '' then
|
|
EpiPartRec = Database_Services('ReadDataRow', 'EPI_PART', EpiPartNo)
|
|
If Error_Services('NoError') then
|
|
ReactorTypes = 'ASM,ASM+,HTR,EPIPRO,GAN'
|
|
Locate ReactorType in ReactorTypes using ',' setting cPos then
|
|
If MinutesPerWafer NE '' then MinutesPerWafer = Iconv(MinutesPerWafer, 'MD3')
|
|
EpiPartRec<EPI_PART_MINUTES_PER_WAFER_SCHEDULER$, cPos> = MinutesPerWafer
|
|
Database_Services('WriteDataRow', 'EPI_PART', EpiPartNo, EpiPartRec, True$)
|
|
If Error_Services('NoError') then
|
|
Memory_Services('SetValue', ServiceModule : '*GetMinutesPerWaferScheduler*' : EpiPartNo : '*' : ReactorType, Oconv(MinutesPerWafer, 'MD3'))
|
|
end
|
|
end
|
|
end
|
|
end else
|
|
* Error_Services('Add', 'EpiPartNo, ReactorType or MinutesPerWafer argument was missing from the ' : Service : ' service.')
|
|
Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.')
|
|
end
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetMinutesPerWaferScheduler
|
|
//
|
|
// Returns the minutes per wafer needed for scheduling associated to the indicated Epi Part and reactor type.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetMinutesPerWaferScheduler(EpiPartNo, ReactorType=REACTORTYPES)
|
|
|
|
Convert @Lower_Case to @Upper_Case in ReactorType
|
|
ServiceKeyID := '*' : EpiPartNo : '*' : ReactorType
|
|
MinutesPerWafer = Memory_Services('GetValue', ServiceKeyID)
|
|
|
|
If MinutesPerWafer EQ '' then
|
|
If EpiPartNo NE '' AND ReactorType NE '' then
|
|
EpiPartRec = Database_Services('ReadDataRow', 'EPI_PART', EpiPartNo)
|
|
If Error_Services('NoError') then
|
|
ReactorTypes = 'ASM,ASM+,HTR,EPIPRO,GAN'
|
|
Locate ReactorType in ReactorTypes using ',' setting cPos then
|
|
MinutesPerWafer = EpiPartRec<EPI_PART_MINUTES_PER_WAFER_SCHEDULER$, cPos>
|
|
If (MinutesPerWafer + 0) NE 0 then
|
|
MinutesPerWafer = Oconv(MinutesPerWafer, 'MD3')
|
|
Memory_Services('SetValue', ServiceKeyID, MinutesPerWafer)
|
|
end else
|
|
Error_Services('Add', 'Minutes per wafer for Epi Part #' : EpiPartNo : ' is zero. Reactor Type: ' : ReactorType)
|
|
end
|
|
end
|
|
end
|
|
end else
|
|
Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.')
|
|
end
|
|
end
|
|
|
|
Response = MinutesPerWafer
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetIdealWafersPerDayScheduler
|
|
//
|
|
// Returns the ideal number of wafers per day associated to the indicated Epi Part and reactor type.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetIdealWafersPerDayScheduler(EpiPartNo, ReactorType=REACTORTYPES, MinutesPerWafer)
|
|
|
|
Convert @Lower_Case to @Upper_Case in ReactorType
|
|
ServiceKeyID := '*' : EpiPartNo : '*' : ReactorType : '*' : MinutesPerWafer
|
|
WafersPerDay = Memory_Services('GetValue', ServiceKeyID)
|
|
|
|
If WafersPerDay EQ '' then
|
|
If EpiPartNo NE '' AND ReactorType NE '' then
|
|
If MinutesPerWafer EQ '' then MinutesPerWafer = Epi_Part_Services('GetMinutesPerWaferScheduler', EpiPartNo, ReactorType)
|
|
If MinutesPerWafer EQ '' OR MinutesPerWafer EQ 0 then
|
|
Error_Services('Add', 'Unexpected minutes per wafer value in EPI_PART #' : EpiPartNo)
|
|
end
|
|
If Error_Services('NoError') then
|
|
WafersPerDay = 1440 / MinutesPerWafer
|
|
WafersPerDay = Oconv(Iconv(WafersPerDay, 'MD2'), 'MD2')
|
|
Memory_Services('SetValue', ServiceKeyID, WafersPerDay)
|
|
end
|
|
end else
|
|
Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.')
|
|
end
|
|
end
|
|
Response = WafersPerDay
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetAdjustedWafersPerDayScheduler
|
|
//
|
|
// Returns the adjusted number of wafers per day associated to the indicated Epi Part and reactor type.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetAdjustedWafersPerDayScheduler(EpiPartNo, ReactorType=REACTORTYPES, MinutesPerWafer)
|
|
|
|
Convert @Lower_Case to @Upper_Case in ReactorType
|
|
ServiceKeyID := '*' : EpiPartNo : '*' : ReactorType
|
|
|
|
WafersPerDay = Memory_Services('GetValue', ServiceKeyID)
|
|
|
|
If WafersPerDay EQ '' then
|
|
If EpiPartNo NE '' AND ReactorType NE '' then
|
|
If MinutesPerWafer EQ '' then MinutesPerWafer = Epi_Part_Services('GetMinutesPerWaferScheduler', EpiPartNo, ReactorType)
|
|
If Error_Services('NoError') then
|
|
Utilization = Epi_Part_Services('GetReactorUtilization', ReactorType)
|
|
If Error_Services('NoError') then
|
|
IdealWafersPerDay = Epi_Part_Services('GetIdealWafersPerDayScheduler', EpiPartNo, ReactorType, MinutesPerWafer)
|
|
WafersPerDay = IdealWafersPerDay * (Utilization / 100)
|
|
WafersPerDay = Oconv(Iconv(WafersPerDay, 'MD2'), 'MD2')
|
|
If ReactorType _EQC 'EpiPro' then WafersPerDay = WafersPerDay * 2
|
|
Memory_Services('SetValue', ServiceKeyID, WafersPerDay)
|
|
end
|
|
end
|
|
end else
|
|
Error_Services('Add', 'EpiPartNo or ReactorType argument was missing from the ' : Service : ' service.')
|
|
end
|
|
end
|
|
|
|
Response = WafersPerDay
|
|
|
|
end service
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// GetEpiParts
|
|
//
|
|
// Input: ReactType
|
|
//
|
|
// Output: A @FM delimited list of Epi Part keys.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
Service GetEpiParts(ReactType=REACTORTYPES)
|
|
|
|
ErrorMsg = ''
|
|
EpiPartList = ''
|
|
If ReactType NE '' then
|
|
If ReactType EQ 'EpiPro' then ReactType = 'EPP'
|
|
EpiPartList = ''
|
|
Query = 'SELECT EPI_PART WITH REACT_TYPE EQ ':Quote(ReactType)
|
|
RList(Query, TARGET_ACTIVELIST$, '', '', '')
|
|
StatusCode = ''
|
|
If Not(Get_Status(StatusCode)) then
|
|
EOF = False$
|
|
Loop
|
|
Readnext EpiPartKey else EOF = True$
|
|
Until EOF
|
|
EpiPartList<-1> = EpiPartKey
|
|
Repeat
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. RList call failed. Error code: ':StatusCode:'.'
|
|
end
|
|
end else
|
|
ErrorMsg = 'Error in ':Service:' service. Null ReactType passed in!'
|
|
end
|
|
|
|
If ErrorMsg EQ '' then
|
|
Response = EpiPartList
|
|
end else
|
|
Error_Services('Add', ErrorMsg)
|
|
end
|
|
|
|
End Service
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Internal GoSubs
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|