Click here to Skip to main content
Click here to Skip to main content

An Easy way to interface with semiconductor SECS/GEM equipment in .NET

, 26 Dec 2005
Rate this:
Please Sign up or sign in to vote.
This article provides an introduction on how to interface with SECS/GEM compliant equipment using Insphere SecsToTool.Net.

Introduction to SECS/GEM

SEMI.org, an international organization of semiconductor manufacturers, is an organization body that governs the standards for semiconductor manufacturing equipments. Often the standard is referred to as SECS/GEM standard, which includes the SECS-I, SECS-II, HSMS and GEM standards.

  • SECS-I defines a point to point communication protocol for RS-232 serial communications. This is a much slower media when compared to HSMS.
  • SECS-II defines how the information is passed between the equipment and the host in the form of low level messages (in the bits and bytes interpretation).
  • HSMS defines a point to point communication protocol for TCP/IP ethernet communication.
  • GEM defines how to use the core SECS-II messages to perform particular tasks, such as event report, data collection and recipe management. It also defines the behavior of the equipment while interfacing with the host.

As said earlier, SECS-II defines a low level message content between the equipment and the host. For example, the following message is sent from device 66 telling the host that the temperature at point T1 has exceeded a preset process limit:

10000000     R=1 (to the host)
00101110     Device Code=66
00000101     Stream 5, W=0
00000001     Function 1
10000000     E=1
00000001     Block 1
00000000
00000000     System bytes=0
00000000
00000000
00000001     List
00000011     3 Elements
00100001     Binary Item next byte length
00000001     1 byte long
00000100     Alarm set, category 4
01100101     Item, 1-byte integer, next byte length
00000001     1 byte long
00010001     Alarm 17
01000001     Item, ASCII, next byte length
00000111     7 characters
01010100     ASCII T
00110001     ASCII 1
00100000     ASCII space
01001000     ASCII H
01001001     ASCII I
01000111     ASCII G
01001000     ASCII H

This is a very tedious job if you want to interpret the raw binary messages so that your application can process it. Today there are a couple of third-party SECS/GEM drivers that provide a high level application programming interface (API) for use in your host application.

Introduction to SecsToTool.NET

Now you may wonder, what is SecsToTool.NET?

SecsToTool.NET is a connectivity solution for the semiconductor equipment that supports SECS/GEM communication interface. The SecsToTool.NET driver SDK is designed to provide high level method call/reply and event driven environment for your host application to communicate with the equipment. By using SecsToTool.NET, you can concentrate on developing a solid application rather than being sidetracked by the lower level SECS/GEM message protocols and formats which are very tedious.

The host SECS library features a fully CLS (Common Language Runtime) compliant API and can be used from any of the .NET programming languages such as C#, VB, J#, C++, Pyton, etc. To interface with SECS/GEM capable equipment, we can focus our development effort on message handling in the well formatted data item and business logic with minimal code written.

The SDK comes with a Model Builder Editor that lets you quickly and easily model the equipment SECS/GEM capability that communicates with your host application. Rather than coding the formats, communication settings, other equipments modeling into your application, you can use SecsToTool Model Builder to configure it and generate the data in a single XML file.

Download a copy of SecsToTool.NET SDK from here. The SDK includes a full developer API reference and a user guide documentation for you to quickly get started on using SecsToTool.NET.

Interfacing with the equipment using SecsToTool.NET

The following code shows you how to perform initialization and establish communication with the equipment using SecsToTool.NET. All the APIs are .NET compliant and provide an event-driven environment:

using System;

// Import the SecsToTool Driver namespace
using Insphere.SecsToTool.Application;
// Import the SecsDataItem namespance
using Insphere.SecsToTool.Common;

// Declare a simple delegate to broadcast our 
// message to subscriber.
public delegate void DelInitializationExample(string message);

We also declare a simple delegate to broadcast our message to a higher layer handler. E.g. Equipment Manager. You can declare a proper EventArgs that is compliant to the .NET programming guidelines.

The following class demonstrates how to develop a Daisy-chain type of initialization approach. First, we declare an InitializationChainContext as a context information that is assigned to our hostController.Tag. The tag assigned will be reset for every transaction, which means it will not be carried forward to the next transaction unless we set it again. Every transaction that is involved in this daisy chain ring is assigned an InitializationChainContext variable:

[Editor comment: Line breaks used to avoid scrolling.]

// This class provides the example for Host to perform 
// Initialization to Equipment upon Establish 
// Communication through S1F13.
// This example provides user a guide of how to perform 
// initialization using the Asynchronous Daisy Chain 
// approach
public class InitializationExample {

    // Declare the SECsHost object
    private SECsHost hostController;

    // Declare a Daisy chain context
    private const string InitializationChainContext = 
                         "Establish Communication Chain";

    
    // Declare a simple event to broadcast our activity
    public event DelInitializationExample MessageIn;

    // Constructor instance
    public InitializationExample() {
      // create an instance of SECsHost object
      hostController = SECsFactory.CreateInstance();

      // hook up event sent by the equipment.
      hostController.SECsPrimaryIn += new Insphere.SecsToTool.
        Application.SECsBase.SECsPrimaryInEventHandler(OnPrimaryIn);

      // hook up reply/acknowledgement sent by the equipment
      hostController.SECsSecondaryIn += new Insphere.SecsToTool.
        Application.SECsBase.SECsSecondaryInEventHandler(OnSecondaryIn);

      // hook up the error messages from the library
      hostController.SECsHostError += new Insphere.SecsToTool.
        Application.SECsBase.SECsHostErrorHandler(OnErrorNotification);
    }

In the constructor, we create an instance of SECsHost object that provides a library of methods for your host application to send messages to the equipment. The hostController subscribes to the following events:

  • SECsPrimaryIn - this is the event initiated by the equipment to host.
  • SECsSecondaryIn - this is the reply or acknowledgement from the equipment. When the host sends a message to the equipment, the equipment will send a reply or acknowledgement via the secondary event.
  • SECsHostError - this is the error generated by the SECsHost compiler. When the equipment sends an illegal message or invalid formats, the host will fire an error to notify the host application:

[Editor comment: Line breaks used to avoid scrolling.]

// Start Initialization to the equipment
public void StartInitialization() {
    Logger("Step 1: Initialize the Tool Model");
    hostController.Initialize(AppDomain.
       CurrentDomain.BaseDirectory + "\\ToolModel1.xml");
    Logger("Step 2: Open HSMS connection port");
    hostController.Connect(); 
    // Now we will wait for the Equipment to 
    // acknowledge and notify at the Primary Event
    }

This method is our sample application entry point to trigger a series of methods to be executed in a daisy-chain fashion. (Meaning it is executed in the form of RING, when the reply is OK, the execution continues). hostController triggers a Connect method to open the HSMS connection with the equipment.

// Primary event handler
private void OnPrimaryIn(object sender, 
                 SECsPrimaryInEventArgs e) {
    switch (e.EventId) {
        // this signals that we have successfully 
        // connected to the equipment
        case PrimaryEventType.Connected:    
            Logger("Equipment Connected");
            // Use Tag to set the context for our 
            // Daisy Chain method
            hostController.Tag = InitializationChainContext;

            Logger("Step 3: Initiate Establish " + 
                    "Communication via S1F13 to equipment");
            // Trigger the S1F13 message to equipment. Now note 
            // that our establish communication carry a 
            // InitializationChain Context
            hostController.EstablishCommunication(); 

            // Wait for the reply from Equipment in 
            // Secondary Event
            break;
        case PrimaryEventType.EventReport:
            Logger("Received event: " + 
                e.Inputs.DataItem["Ln"]["CEID"].Value);
            break;
    }
}

When equipment accepts the connection, it sends the connected event to our PrimaryIn.

The rest of the following code, shows how to handle the reply or acknowledgement from the equipment and continue the daisy chain execution until it hits the final line:

// Secondary Event Handler
private void OnSecondaryIn(object sender, 
                  SECsSecondaryInEventArgs e) {
    switch (e.EventId) {
        // S1F14. Replies from S1F13 message
        case SecondaryEventType.EstablishCommunicationReply:  
            // Check if equipment accept our S1F13 request
            if (e.Outputs.DataItem["Ln"]["COMMACK"].Value.ToString() == "0")
            { // 0 means OK
                Logger("Establish Communication accepted");
                // Check if it is a Initialization Chain Context
                if (e.Tag.Equals(InitializationChainContext)) {
                    // Continue our initialization

                    // Keep setting the Daisy Chain context
                    hostController.Tag = InitializationChainContext;

                    Logger("Step 4: Synchronous Host current " + 
                                   "date and time with Equipment");
                    hostController.DateTimeSetRequest(); 
                }
            }
            else
                Logger("Establish Communication not accepted. " + 
                                      "Initialization terminated!");
                
            break;

        // S2F32. Acknowledgement from our DateTimeSetRequest()
        case SecondaryEventType.DateTimeSetReply: 
            if (e.Outputs.DataItem["TIACK"].Value.ToString() == "0")
            { // 0 Means OK
                Logger("DateTimeSet acknowledged OK");
                // Check if it is a Initialization Chain Context
                if (e.Tag.Equals(InitializationChainContext)) {
                    // Continue our initialization

                    // Keep setting the Daisy Chain context
                    hostController.Tag = InitializationChainContext;

                    Logger("Step 5: Disable all the alarm " + 
                                  "activation status at Equipment");
                    hostController.EnableAlarm(false); 
                }
            }
            break;

        // S5F4. Acknowledgement from our 
        // EnableAlarm(false) - Disable all alarm
        case SecondaryEventType.DisableAlarmReportReply: 
            if (e.Outputs.DataItem["ACKC5"].Value.ToString() == "0") 
            {
                Logger("Disable all Alarms accepted by equipment");

                // Check if it is a Initialization Chain Context
                if (e.Tag.Equals(InitializationChainContext)) {
                    // Continue our initialization

                    // Keep setting the Daisy Chain context
                    hostController.Tag = InitializationChainContext;

                    Logger("Step 6: Enable all the alarm as " + 
                                   "defined in our ToolModel1.xml");
                    hostController.EnableAlarm(true); 
                }
            }
            else
                Logger("Disable all Alarms not accepted by " + 
                           "equipment. Initialization terminated!");

            break;

        // S5F4. Enable Alarm acknowledgement
        case SecondaryEventType.EnableAlarmReportReply: 
            if (e.Outputs.DataItem["ACKC5"].Value.ToString() == "0") {
                Logger("Enable all Alarms accepted by equipment");
            
                // Check if it is a Initialization Chain Context
                if (e.Tag.Equals(InitializationChainContext)) {
                    // Continue our initialization

                    // Keep setting the Daisy Chain context
                    hostController.Tag = InitializationChainContext;

                    Logger("Step 7: Delete equipment " + 
                                 "existing report definition");
                    hostController.DefineReports(
                                    DefineReportType.DeleteReports);

                }
            }
            else
                Logger("Enable Alarms not accepted by " + 
                       "equipment. Initialization terminated!");

            break;
        // S2F34. Delete all reports acknowledgement 
        case SecondaryEventType.DeleteAllReportsReply: 
            if (e.Outputs.DataItem["DRACK"].Value.ToString() == "0") 
            {
                Logger("Delete all report accepted");

                // Check if it is a Initialization Chain Context
                if (e.Tag.Equals(InitializationChainContext)) {
                    // Continue our initialization

                    // Keep setting the Daisy Chain context
                    hostController.Tag = InitializationChainContext;

                    Logger("Step 8: Define all reports and its " + 
                            "associated variables as defined in out " + 
                            "ToolModel1.xml");
                    hostController.DefineReports(
                               DefineReportType.DefineReports);
                }
            }
            else
                Logger("Delete all report not accepted. " + 
                                     "Initialization terminated!");
            break;

        // S2F34. Define reports acknowledgement
        case SecondaryEventType.DefineReportsReply: 
            if (e.Outputs.DataItem["DRACK"].Value.ToString() == "0") 
            {
                Logger("Define all report accepted");

                // Check if it is a Initialization Chain Context
                if (e.Tag.Equals(InitializationChainContext)) {
                    // Continue our initialization

                    // Keep setting the Daisy Chain context
                    hostController.Tag = InitializationChainContext;

                    Logger("Step 9: Unlink equipment event " + 
                                               "report definition");
                    hostController.LinkEventReport(
                                 LinkEventReportType.UnlinkEventReports); 
                }
            }
            else
                Logger("Define all report not accepted. " + 
                                      "Initialization terminated!");

            break;

        // S2F36 Unlink event report acknowledgement
        case SecondaryEventType.UnlinkEventReportsReply: 
            if (e.Outputs.DataItem["LRACK"].Value.ToString() == "0") 
            {
                Logger("Unlink event report is accepted");

                // Check if it is a Initialization Chain Context
                if (e.Tag.Equals(InitializationChainContext)) {
                    // Continue our initialization

                    // Keep setting the Daisy Chain context
                    hostController.Tag = InitializationChainContext;

                    Logger("Step 10: Link event report definition " + 
                       "to equipment as defined in our ToolModel1.xml");
                    hostController.LinkEventReport(
                                  LinkEventReportType.LinkEventReports); 
                }
            }
            else
                Logger("Unlink event report is not accepted. " + 
                                       "Initialization terminated!");

            break;

        // S2F36 Link event report acknowledgement
        case SecondaryEventType.LinkEventReportsReply: 
            if (e.Outputs.DataItem["LRACK"].Value.ToString() == "0") 
            {
                Logger("Unlink event report is accepted");

                Logger("Daisy Chain Demo completed.");
            
                // This will disconnect our connection to equipment
                hostController.Disconnect();
                Logger("Communication disconnected");
            }
            else
                Logger("Unlink event report is not accepted. " + 
                                     "Initialization terminated!");
            break;
    }
}

private void Logger(string message) {
    if (MessageIn != null) 
        MessageIn(message);
}

private void OnErrorNotification(object sender, 
                          SECsHostErrorEventArgs e) {
    Logger("Error source: " + e.Source + 
                          ", Message: " + e.Message);
}

Sample high level log contents

The message transacted between the semiconductor equipment and the host can be represented in the semiconductor markup language (SML), which is pretty much similar to the XML structure:

Sending @12/21/2005 10:52:53 PM
S2F33 [00000008] W
 <L[2]
  <U4[3] 100>
  <L[0]
  >
 >
.
Received @12/21/2005 10:52:54 PM
S2F34 [00000008]
 <B[1] 00
 >
.
Sending @12/21/2005 10:52:54 PM
S2F33 [00000009] W
 <L[2]
  <U4[3] 101>
  <L[3]
   <L[2]
    <U4[3] 100>
    <L[5]
     <U4[3] 200>
     <U4[3] 201>
     <U4[3] 202>
     <U4[3] 203>
     <U4[3] 204>
    >
   >
   <L[2]
    <U4[3] 101>
    <L[2]
     <U4[3] 205>
     <U4[3] 207>
    >
   >
   <L[2]
    <U4[3] 102>
    <L[0]
    >
   >
  >
 >
.
Received @12/21/2005 10:52:54 PM
S2F34 [00000009]
 <B[1] 00>
.
Sending @12/21/2005 10:52:54 PM
S2F35 [00000010] W
 <L[2]
  <U4[3] 102>
  <L[3]
   <L[2]
    <U4[4] 2000>
    <L[0]
    >
   >
   <L[2]
    <U4[4] 2001>
    <L[0]
    >
   >
   <L[2]
    <U4[4] 2002>
    <L[0]
    >
   >
  >
 >
.
Received @12/21/2005 10:52:54 PM
S2F36 [00000010]
 <B[1] 00>

Sample low level SECS messages log contents

This is the original message sent and received in the SecsToTool.NET compiler level. All this complexity will be transparent to the host application level. SecsToTool.NET does the interpretation and parsing of the raw messages and represents it in a human readable structure:

--> 12/22/2005 12:55:17 AM Length [00 00 00 0A]
--> 12/22/2005 12:55:17 AM SelectReq[FC FC 00 00 00 01 00 00 00 01]
<-- 12/22/2005 12:55:17 AM Length [00 00 00 0A]
<-- 12/22/2005 12:55:17 AM SelectRsp[FC FC 00 00 00 02 00 00 00 01]
--> 12/22/2005 12:55:17 AM Length [00 00 00 0A]
--> 12/22/2005 12:55:17 AM LinktestReq[FC FC 00 00 00 05 00 00 00 02]
<-- 12/22/2005 12:55:18 AM Length [00 00 00 0A]
<-- 12/22/2005 12:55:18 AM LinktestRsp[FF FF 00 00 00 06 00 00 00 02]
--> 12/22/2005 12:55:18 AM Length [00 00 00 0C]
--> 12/22/2005 12:55:18 AM Header [00 03 81 0D 00 00 00 00 00 04]
--> 12/22/2005 12:55:18 AM Data   [01 00]
<-- 12/22/2005 12:55:22 AM Length [00 00 00 24]
<-- 12/22/2005 12:55:22 AM Header [00 03 01 0E 00 00 00 00 00 04]
<-- 12/22/2005 12:55:22 AM Data   [01 02 21 01 00 01 02 41 07 66 73 64 61 
                                   66 61 66 41 08 66 64 61 66 73 61 66 64]
--> 12/22/2005 12:55:22 AM Length [00 00 00 1C]
--> 12/22/2005 12:55:22 AM Header [00 03 82 1F 00 00 00 00 00 05]
--> 12/22/2005 12:55:22 AM Data   [41 10 32 30 30 35 31 32 32 32 
                                   30 30 35 35 32 32 30 30]
<-- 12/22/2005 12:55:23 AM Length [00 00 00 0D]
<-- 12/22/2005 12:55:23 AM Header [00 03 02 20 00 00 00 00 00 05]
<-- 12/22/2005 12:55:23 AM Data   [21 01 00]

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Insphere Technology
Web Developer
Singapore Singapore
Insphere Technology provides integration services for the semiconductor industry. It also offers a SECS/GEM driver (SecsToTool.Net) that allow your host application to interface with the equipment.

Comments and Discussions

 
QuestionContact details PinmemberInsphere Technology24-Nov-11 3:59 
GeneralCost PinmemberDanZed13-Jan-10 4:51 
GeneralHi. I need some help PinmemberPhilya10-Dec-09 2:37 
QuestionHelp! Help! Help! PinmemberJeffreychou14-Oct-09 16:15 
QuestionThread context of events Pinmembertmichals4-Jan-06 12:51 
AnswerRe: Thread context of events PinmemberInsphere Technology4-Jan-06 17:38 
GeneralRe: Thread context of events Pinmembertmichals5-Jan-06 8:56 
GeneralNice! Pinmembergreg31165328-Dec-05 16:33 
QuestionMultiple equipment support... PinmemberPhillip M. Hoff27-Dec-05 15:44 
AnswerRe: Multiple equipment support... PinmemberInsphere Technology27-Dec-05 19:45 
QuestionCustomization capabilities... PinmemberPhillip M. Hoff27-Dec-05 7:31 
AnswerRe: Customization capabilities... PinmemberInsphere Technology27-Dec-05 15:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141220.1 | Last Updated 27 Dec 2005
Article Copyright 2005 by Insphere Technology
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid