345 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			345 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| Function NDW_ROTR_WAFER_DETAILS_EVENTS(CtrlEntId, Event, @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 Infineon.
 | |
| 
 | |
|     Name        :   NDW_ROTR_WAFER_DETAILS_EVENTS
 | |
| 
 | |
|     Description :   This function acts as a commuter module for all events related to this window.
 | |
| 
 | |
|     Notes       :   Commuter Modules are automatically called from the Promoted_Events function which is called by the
 | |
|                     application-specific promoted event handler. This makes it possible to add QuickEvents that need to
 | |
|                     execute Basic+ logic without having use the Form Designer to make the association, although this is
 | |
|                     limited to the events which are currently promoted.
 | |
| 
 | |
|                     If the form needs to call the commuter module directly then the QuickEvent parameters should be
 | |
|                     formatted like this:
 | |
| 
 | |
|                         '@SELF','@EVENT',['@PARAM1','@PARAMx']
 | |
| 
 | |
|     Parameters  :
 | |
|         CtrlEntId   [in] -- The fully qualified name of the control calling the promoted event
 | |
|         Event       [in] -- The event being executed. See the Notes section regarding "PRE" events
 | |
|         Param1-15   [in] -- Additional event parameter holders
 | |
|         EventFlow  [out] -- Set to 1 or 0 so the calling event knows whether or not to chain forward. See comments in
 | |
|                             EVENT_SETUP insert
 | |
| 
 | |
|     History     :   (Date, Initials, Notes)
 | |
|         09/17/18    djs     Created initial commuter module.
 | |
|         11/20/18    djs     Updated the BTN_VIEW_WAFER_IMAGE.CLICK event to support the new ROTR wafer image naming
 | |
|                             convention, which includes the tencor recipe in the name.
 | |
| 
 | |
| ***********************************************************************************************************************/
 | |
| 
 | |
| #pragma precomp SRP_PreCompiler
 | |
| #Window NDW_ROTR_WAFER_DETAILS
 | |
| 
 | |
| DECLARE SUBROUTINE Set_Property, End_Dialog, Send_Event, Set_Status, obj_WO_Mat, Btree.Extract, Utility
 | |
| DECLARE SUBROUTINE ErrMsg, Set_Property, obj_AppWindow, Send_Event, obj_WO_Mat_QA, obj_Tables
 | |
| DECLARE SUBROUTINE Start_Window, End_Window, Database_Services, QA_Services, Form_Services, Forward_Event
 | |
| DECLARE SUBROUTINE SRP_EditTable_Manager, SRP_Show_Window, Rds_Services, Post_Event, Yield
 | |
| 
 | |
| DECLARE FUNCTION Get_Property, Get_Status, Dialog_Box, obj_WM_Out, set_WinMsgVal, Form_Services, Environment_Services
 | |
| DECLARE FUNCTION Msg, obj_WO_Mat, Send_Message, obj_Tables, Start_Window, End_Window, QA_Services, Utility
 | |
| DECLARE FUNCTION SRP_EditTable_Manager, Database_Services, Material_Services, Rds_Services, RGB, Min, Max
 | |
| 
 | |
| $INSERT LOGICAL
 | |
| $INSERT EVENT_SETUP
 | |
| $INSERT MSG_EQUATES
 | |
| $INSERT LSL_USERS_EQU
 | |
| $INSERT APPCOLORS
 | |
| $INSERT CLEAN_INSP_EQUATES
 | |
| 
 | |
| Equ Tab$                    to \09\
 | |
| Equ CRLF$                   to \0D0A\
 | |
| Equ LF$                     to \0A\
 | |
| Equ Comma$                  to ','
 | |
| 
 | |
| ErrTitle = 'Error in NDW_ROTR_Wafer_Details_Events'
 | |
| ErrorMsg = ''
 | |
| 
 | |
| Result = ''
 | |
| 
 | |
| SubclassInfo    = Form_Services('FindSubclassControl')
 | |
| Subclass        = SubclassInfo<1>
 | |
| 
 | |
| // Update the arguments so that the OpenInsight OLE event will treate the ActiveX event as a native event handler.
 | |
| If Event EQ 'OLE' then
 | |
|     Transfer Event to OIEvent
 | |
|     Transfer Param1 to Event
 | |
|     Transfer Param2 to Param1
 | |
|     Transfer Param3 to Param2
 | |
| *    Transfer Param4 to Param3
 | |
| *    Transfer Param5 to Param4
 | |
| *    Transfer Param6 to Param5
 | |
| *    Transfer Param7 to Param6
 | |
| *    Transfer Param8 to Param7
 | |
| end
 | |
| 
 | |
| GoToEvent Event for CtrlEntID
 | |
| 
 | |
| Return EventFlow else EVENT_CONTINUE$
 | |
| 
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| // Events
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| Event WINDOW.CREATE(CreateParam)
 | |
| 
 | |
|     CleanInspKey = CreateParam<1>
 | |
|     ScanIndex    = CreateParam<2>
 | |
|     Set_Property(@Window, '@SCANINDEX', ScanIndex)
 | |
|     CleanInspRec = Database_Services('ReadDataRow', 'CLEAN_INSP', CleanInspKey)
 | |
|     RDSNo        = CleanInspRec<CLEAN_INSP_RDS_NO$>
 | |
|     ScanRecipe   = CleanInspRec<CLEAN_INSP_SCAN_RECIPE$, ScanIndex>
 | |
|     SODReadings  = CleanInspRec<CLEAN_INSP_SCAN_SOD_PER_WAFER$, ScanIndex>
 | |
|     SortReadings = CleanInspRec<CLEAN_INSP_SCAN_SORT_PER_WAFER$, ScanIndex>
 | |
|     ScanDTM      = CleanInspRec<CLEAN_INSP_INSP_TEST_RUN_DTM$, ScanIndex>
 | |
|     ScanMin      = CleanInspRec<CLEAN_INSP_SCAN_SUM_OF_DEF_MIN$, ScanIndex>
 | |
|     ScanMax      = CleanInspRec<CLEAN_INSP_SCAN_SUM_OF_DEF_MAX$, ScanIndex>
 | |
|     ScanAvg      = CleanInspRec<CLEAN_INSP_SCAN_SUM_OF_DEF_AVG$, ScanIndex>
 | |
|     SpecRecipes  = CleanInspRec<CLEAN_INSP_SPEC_SURFSCAN_RECIPE$>
 | |
|     SpecMaxVals  = CleanInspRec<CLEAN_INSP_SPEC_SURF_DEFECTS$>
 | |
|     SpecMax      = ''
 | |
|     Locate ScanRecipe in SpecRecipes using @VM setting vPos then
 | |
|         SpecMax = SpecMaxVals<1, vPos>
 | |
|     end
 | |
| 
 | |
|     If SODReadings EQ '' then
 | |
|         // Check metrology for individual SOD values again. (This is initially done within Metrology_Services
 | |
|         // when the run data is first imported into OpenInsight.)
 | |
|         SODWaferArray   = ''
 | |
|         SODWaferArray   = QA_Services('GetSODPerWafer', RDSNo, ScanRecipe, ScanDTM)
 | |
|         If SODWaferArray NE '' then
 | |
|             WaferNos = SODWaferArray<1>
 | |
|             SODVals  = SODWaferArray<2>
 | |
|             SortVals = SODWaferArray<3>
 | |
|             For each WaferNo in WaferNos using @VM                                   
 | |
|                 If WaferNo NE '' then
 | |
|                     CleanInspRec<CLEAN_INSP_SCAN_SOD_PER_WAFER$, ScanIndex, WaferNo>  = SODVals<1, WaferNo>
 | |
|                     CleanInspRec<CLEAN_INSP_SCAN_SORT_PER_WAFER$, ScanIndex, WaferNo> = SortVals<1, WaferNo>
 | |
|                 end
 | |
|             Next Wafer
 | |
|             Database_Services('WriteDataRow', 'CLEAN_INSP', CleanInspKey, CleanInspRec, True$, False$, True$)
 | |
|             SODReadings  = CleanInspRec<CLEAN_INSP_SCAN_SOD_PER_WAFER$, ScanIndex>
 | |
|             SortReadings = CleanInspRec<CLEAN_INSP_SCAN_SORT_PER_WAFER$, ScanIndex>
 | |
|         end else
 | |
|             MsgDef = ''
 | |
|             MsgDef<MTEXT$>  = 'Individual wafer information not available for the selected scan. ' | 
 | |
|                             : 'Please contact FI admin for additional assistance.'
 | |
|             MsgDef<MTYPE$>  = 'BO'
 | |
|             MsgDef<MICON$>  = '!'
 | |
|             MsgDef<MMODAL$> = 'W'
 | |
|             PrevCursor = Set_Property("SYSTEM", "CURSOR", "A")
 | |
|             Yield()
 | |
|             Response = Msg(@Window, MsgDef)
 | |
|             Send_Event(@Window, 'CLOSE')
 | |
|         end
 | |
|     end
 | |
|     Convert @SVM to @VM in SODReadings
 | |
|     Convert @SVM to @VM in SortReadings
 | |
|     DataArray    = ''
 | |
|     DataArray<1> = SODReadings
 | |
|     DataArray<2> = SortReadings
 | |
|     Set_Property(@Window : '.EDL_CLEAN_INSP_KEY', 'TEXT', CleanInspKey)
 | |
|     Set_Property(@Window : '.EDL_RDS_NO', 'TEXT', RDSNo)
 | |
|     Set_Property(@Window : '.EDL_SCAN_RECIPE', 'TEXT', ScanRecipe)
 | |
|     Set_Property(@Window : '.EDL_SCAN_DTM', 'TEXT', OConv(ScanDTM, 'DT/4^HS'))
 | |
|     Set_Property(@Window : '.EDL_SOD_SPEC_MAX', 'TEXT', SpecMax)
 | |
|     Set_Property(@Window : '.EDT_SOD_READINGS', 'ARRAY', DataArray)
 | |
|     Set_Property(@Window : '.EDL_SOD_MIN', 'TEXT', ScanMin)
 | |
|     Set_Property(@Window : '.EDL_SOD_MAX', 'TEXT', ScanMax)
 | |
|     Set_Property(@Window : '.EDL_SOD_AVG', 'TEXT', OConv(ScanAvg, 'MD3'))
 | |
|     GoSub ColorCells
 | |
|     FormSize     = ''
 | |
|     PrevCursor   = Set_Property("SYSTEM", "CURSOR", "A")
 | |
|     Yield()
 | |
|     SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, FormSize)
 | |
|     
 | |
| end event
 | |
| 
 | |
| 
 | |
| Event WINDOW.CLOSE(CancelFlag)
 | |
|     
 | |
|     End_Dialog(@Window)
 | |
|     
 | |
| end event
 | |
| 
 | |
| 
 | |
| Event EDT_SOD_READINGS.CHANGED(NewData)
 | |
|     
 | |
|     SODReadings = Get_Property(@Window : '.EDT_SOD_READINGS', 'LIST')
 | |
|     MinSOD = SODReadings<1>
 | |
|     MaxSOD = SODReadings<1>
 | |
|     AvgSOD = 0
 | |
|     NumWafers = 0
 | |
|     For each SODVal in SODReadings using @FM
 | |
|         If SODVal NE '' then
 | |
|             MinSOD     = Min(MinSOD, SODVal)
 | |
|             MaxSOD     = Max(MaxSOD, SODVal)
 | |
|             AvgSOD    += SODVal
 | |
|             NumWafers += 1
 | |
|         end
 | |
|     Next SODVal
 | |
|     If NumWafers NE 0 then AvgSOD = AvgSOD / NumWafers
 | |
|     Set_Property(@Window : '.EDL_SOD_MIN', 'TEXT', MinSOD)
 | |
|     Set_Property(@Window : '.EDL_SOD_MAX', 'TEXT', MaxSOD)
 | |
|     Set_Property(@Window : '.EDL_SOD_AVG', 'TEXT', AvgSOD)
 | |
|     GoSub ColorCells
 | |
|     
 | |
| end event
 | |
| 
 | |
| 
 | |
| Event BTN_SAVE.CLICK()
 | |
|     
 | |
|     CleanInspKey = Get_Property(@Window : '.EDL_CLEAN_INSP_KEY', 'TEXT')
 | |
|     CleanInspRec = Database_Services('ReadDataRow', 'CLEAN_INSP', CleanInspKey)
 | |
|     SODReadings  = Get_Property(@Window : '.EDT_SOD_READINGS', 'LIST')
 | |
|     SODMin       = Get_Property(@Window : '.EDL_SOD_MIN', 'TEXT')
 | |
|     SODMax       = Get_Property(@Window : '.EDL_SOD_MAX', 'TEXT')
 | |
|     SODAvg       = Get_Property(@Window : '.EDL_SOD_AVG', 'TEXT')
 | |
|     ScanIndex    = Get_Property(@Window, '@SCANINDEX')
 | |
|     CleanInspRec<CLEAN_INSP_SCAN_SUM_OF_DEF_MIN$, ScanIndex> = SODMin
 | |
|     CleanInspRec<CLEAN_INSP_SCAN_SUM_OF_DEF_MAX$, ScanIndex> = SODMax
 | |
|     CleanInspRec<CLEAN_INSP_SCAN_SUM_OF_DEF_AVG$, ScanIndex> = IConv(SODAvg, 'MD3')
 | |
|     Convert @FM to @SVM in SODReadings
 | |
|     CleanInspRec<CLEAN_INSP_SCAN_SOD_PER_WAFER$, ScanIndex> = SODReadings
 | |
|     Database_Services('WriteDataRow', 'CLEAN_INSP', CleanInspKey, CleanInspRec, True$, False$, False$)
 | |
|     Send_Event('CLEAN_INSP', 'READ')
 | |
|     
 | |
| end event
 | |
| 
 | |
| 
 | |
| Event BTN_VIEW_WAFER_IMAGE.CLICK()
 | |
| 
 | |
|     PrevCursor     = Set_Property('SYSTEM', 'CURSOR', 'H')
 | |
|     Yield()
 | |
|     RDSNo          = Get_Property(@Window : '.EDL_RDS_NO', 'TEXT')
 | |
|     Sel            = Get_Property(@Window : '.EDT_SOD_READINGS', 'SELPOS')
 | |
|     TencorRecipe   = Get_Property(@Window : '.EDL_SCAN_RECIPE', 'TEXT')
 | |
|     WaferNo        = Sel<2>
 | |
|     OIAppPath      = Environment_Services('GetApplicationRootPath')
 | |
|     SearchPath     = OIAppPath:'\Wafer_Images\*.*'
 | |
|     WaferImagePath = OIAppPath:'\Wafer_Images\'
 | |
|     FileName    = 'WaferMap_RDSNo_':RDSNo:'_Recipe_':TencorRecipe:'_WaferNo_':WaferNo:'.pdf'
 | |
|     InitDir SearchPath
 | |
|     FileList = DirList()
 | |
|     Locate FileName in FileList using @FM setting fPos then
 | |
|         Utility('RUNWIN', Quote(WaferImagePath:FileName))
 | |
|     end else
 | |
|         WaferMap  = QA_Services('GetWaferImage', RDSNo, WaferNo, TencorRecipe)
 | |
|         Status = ''
 | |
|         If WaferMap NE '' then
 | |
|             Set_Status(0)
 | |
|             OSWrite WaferMap to WaferImagePath:FileName
 | |
|             Status = Get_Status()
 | |
|             Mode = 5 ; // Show
 | |
|             Utility('RUNWIN', Quote(WaferImagePath:FileName), Mode)
 | |
|             PrevCursor = Set_Property("SYSTEM", "CURSOR", "A")
 | |
|             Yield()
 | |
|         end else
 | |
|             MsgDef = ''
 | |
|             MsgDef<MTEXT$>  = 'Individual wafer information not available for the selected scan. ' | 
 | |
|                             : 'Please contact FI admin for additional assistance.'
 | |
|             MsgDef<MTYPE$>  = 'BO'
 | |
|             MsgDef<MICON$>  = '!'
 | |
|             MsgDef<MMODAL$> = 'W'
 | |
|             PrevCursor = Set_Property("SYSTEM", "CURSOR", "A")
 | |
|             Yield()
 | |
|             Response = Msg(@Window, MsgDef)
 | |
|         end
 | |
|     end
 | |
|     
 | |
| end event
 | |
| 
 | |
| 
 | |
| Event EDT_SOD_READINGS.POSCHANGED(NextColumn, NextRow)
 | |
|     
 | |
|     SODData = Get_Property(@Window : '.EDT_SOD_READINGS', 'TEXT')
 | |
|     If SODData EQ '' then
 | |
|         Set_Property(@Window : '.BTN_VIEW_WAFER_IMAGE', 'ENABLED', False$)
 | |
|     end else
 | |
|         Set_Property(@Window : '.BTN_VIEW_WAFER_IMAGE', 'ENABLED', True$)
 | |
|     end
 | |
|     
 | |
| end event
 | |
| 
 | |
| 
 | |
| Event EDT_SOD_READINGS.GOTFOCUS(PrevFocusID)
 | |
|     
 | |
|     SODData = Get_Property(@Window : '.EDT_SOD_READINGS', 'TEXT')
 | |
|     If SODData EQ '' then
 | |
|         Set_Property(@Window : '.BTN_VIEW_WAFER_IMAGE', 'ENABLED', False$)
 | |
|     end else
 | |
|         Set_Property(@Window : '.BTN_VIEW_WAFER_IMAGE', 'ENABLED', True$)
 | |
|     end
 | |
|     
 | |
| end event
 | |
| 
 | |
| 
 | |
| Event OLE_SUBCLASS.OnComboClick(CtrlId, Sel, Value)
 | |
| 
 | |
|     Send_Event(CtrlId, 'LOSTFOCUS')
 | |
| 
 | |
| end event
 | |
| 
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| // Internal GoSubs
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| Setup_OLE_Controls:
 | |
| 
 | |
|     Qualify     = ''
 | |
|     Qualify<1>  = 1
 | |
|     Qualify<4>  = 0
 | |
| 
 | |
| return
 | |
| 
 | |
| 
 | |
| ColorCells:
 | |
| 
 | |
|     OutofSpecColorArray = RED$:@FM:'':@FM:BRED$:@FM:''
 | |
|     InSpecColorArray    = GREEN$:@FM:'':@FM:POS_BLUE$:@FM:''
 | |
|     SODReadingsCtrl     = @Window : '.EDT_SOD_READINGS'
 | |
|     DataArray           = Get_Property(@Window : '.EDT_SOD_READINGS', 'ARRAY')
 | |
|     SODReadings         = DataArray<1>
 | |
|     SortReadings        = DataArray<2>
 | |
|     SODSpecMax          = Get_Property(@Window : '.EDL_SOD_SPEC_MAX', 'TEXT')
 | |
|     SODMin              = Get_Property(@Window : '.EDL_SOD_MIN', 'TEXT')
 | |
|     SODMax              = Get_Property(@Window : '.EDL_SOD_MAX', 'TEXT')
 | |
|     SODAvg              = Get_Property(@Window : '.EDL_SOD_AVG', 'TEXT')
 | |
|     For each SOD in SODReadings using @VM setting vPos
 | |
|         Sort = SortReadings<0, vPos>
 | |
|         Begin Case
 | |
|             Case ( (SOD GT SODSpecMax) and (Sort EQ 'FAIL') )
 | |
|                 stat = Send_Message(SODReadingsCtrl, 'COLOR_BY_POS', 0, vPos, OutofSpecColorArray)
 | |
|             Case SOD GT SODSpecMax
 | |
|                 stat = Send_Message(SODReadingsCtrl, 'COLOR_BY_POS', 1, vPos, OutofSpecColorArray)
 | |
|             Case Sort EQ 'FAIL'
 | |
|                 stat = Send_Message(SODReadingsCtrl, 'COLOR_BY_POS', 2, vPos, OutofSpecColorArray)
 | |
|             Case Otherwise$
 | |
|                 stat = Send_Message(SODReadingsCtrl, 'COLOR_BY_POS', 0, vPos, InSpecColorArray)
 | |
|         End Case
 | |
|     Next SOD
 | |
|     If SODMin GT SODSpecMax then
 | |
|         Set_Property(@Window : '.EDL_SOD_MIN', 'BACKCOLOR', RED$)
 | |
|     end else
 | |
|         Set_Property(@Window : '.EDL_SOD_MIN', 'BACKCOLOR', GREEN$)
 | |
|     end
 | |
|     If SODMax GT SODSpecMax then
 | |
|         Set_Property(@Window : '.EDL_SOD_MAX', 'BACKCOLOR', RED$)
 | |
|     end else
 | |
|         Set_Property(@Window : '.EDL_SOD_MAX', 'BACKCOLOR', GREEN$)
 | |
|     end
 | |
|     If SODAvg GT SODSpecMax then
 | |
|         Set_Property(@Window : '.EDL_SOD_AVG', 'BACKCOLOR', RED$)
 | |
|     end else
 | |
|         Set_Property(@Window : '.EDL_SOD_AVG', 'BACKCOLOR', GREEN$)
 | |
|     end
 | |
|     
 | |
| return
 | |
| 
 |