← Articles
SECS/GEM/10 min read/ views

What HCACK=0 Really Tells You About a SECS/GEM Remote Command

Reading SEMI E5 HCACK and CPACK codes against a real S2F41 wire capture: why HCACK=4 exists, E30 control-state gating, and a retry that won't fire a second START.

SECS/GEMMESSCADATroubleshootingChecklists

HCACK=0 does not mean the wafer moved

A host sends S2F41 Host Command Send with RCMD=START, gets S2F42 back with HCACK=0, and the MES flips the lot to running. Ten seconds later the tool alarms on a pod clamp and never processes anything. Someone opens a ticket that says "SECS is broken."

Nothing is broken. HCACK=0 in SEMI E5 means command performed — appropriate only for a command that finishes inside the transaction. For a START whose real work takes seconds to minutes, the tool should have answered HCACK=4 (accepted, completion signaled later by an event) and the host should have waited for that event instead of the reply. The acknowledge code and the physical outcome are two separate facts, and SECS-II hands you distinct codes for each. Treat them as one and you spend commissioning unwinding MES records.

Read the message, not the abstraction

In SEMI E5 stream 2, the body of S2F41 Host Command Send (HCS) is this shape:

L,2
  <A  RCMD>
  L,n                  <- L,0 when there are no parameters
    L,2
      <A  CPNAME>
      <   CPVAL>

S2F42 Host Command Acknowledge (HCA) answers symmetrically:

L,2
  <B  HCACK>           <- binary, 1 byte
  L,n                  <- usually L,0 unless HCACK=3
    L,2
      <A  CPNAME>
      <B  CPACK>       <- binary, 1 byte

That HCACK and CPACK are binary (B), one byte is a real snag when you hand-write a parser: expect U1, compare the format byte, and it never matches. CPVAL is the opposite problem — E5 does not pin it to one format, so which item format each parameter travels in belongs in the interface spec. This is where two tools diverge.

For anything object-oriented (an E87 carrier, an E94 control job) use the enhanced form S2F49/S2F50. S2F49 Enhanced Remote Command prefixes DATAID and OBJSPEC so you target a specific object instead of firing a bare command at the tool.

HCACK codes worth memorizing (E5):

  • 0 — OK, performed (completes within the transaction)
  • 1 — command does not exist
  • 2 — cannot perform now (wrong state)
  • 3 — at least one parameter invalid — now read the CPACK list
  • 4 — accepted, completion signaled later by a collection event
  • 5 — rejected, already in the requested condition
  • 6 — no such object exists (enhanced form)

That is where E5's definitions stop. A higher value is a vendor extension, not the standard — go find the manual.

CPACK, per parameter, in the S2F42 reply list:

  • 1 — parameter name does not exist
  • 2 — illegal value for CPVAL
  • 3 — illegal format for CPVAL

HCACK=3 with a populated CPACK list is the most useful reject you can design for: it names exactly which CPNAME failed and how. A tool that collapses every parameter problem into a bare HCACK=2 forces a controller-log dig on every failure. Make the vendor return the CPACK list — it is in the standard, and skipping it is a shortcut you pay for later.

HCACK=4 is the contract for "accepted, not done"

Most useful remote commands accept fast and complete slowly. After S2F42 with HCACK=4, the tool still has to clamp, pump down, load the recipe, or clear an interlock. The clean design links each of those to a collection event you've already defined with S2F33 and linked with S2F35, then enabled with S2F37 — so completion of START arrives as a CEID (a ProcessStart or lot-started event), not as the S2F42 reply.

Drive MES lot state from the CEID, never from S2F42. For a recipe select, "complete" is the current-PPID status variable equalling the requested PPID with no recipe alarm — not the acknowledge. If you promote the lot on acceptance, a tool that later fails a local interlock leaves the MES claiming a lot is running that never started.

Gate on state before parameters, parameters before motion

The SEMI E30 control state model splits OFFLINE into sub-states (equipment offline, attempt online, host offline) and ONLINE into LOCAL and REMOTE. A remote command that changes how the equipment operates is legal only in ONLINE/REMOTE. If the tool is ONLINE/LOCAL, the correct answer is HCACK=2.

One detail makes this hard to diagnose: status queries still answer in ONLINE/LOCAL. Throw an S1F3 and S1F4 comes straight back. So the symptom reads as "comms are fine, only commands fail," and people start suspecting the link. Unless the host diagnostic shows control state as LOCAL, someone chases a phantom comms fault while an operator quietly holds the panel.

Validate cheap-to-expensive so a bad command dies before it moves hardware:

  1. ONLINE/REMOTE? else HCACK=2
  2. Command exists? else HCACK=1
  3. Every CPNAME known, every CPVAL in range and format? else HCACK=3 + CPACK
  4. Process state allows it (idle, no active job)? else HCACK=2
  5. Only now start the sequence and return HCACK=4

Parameter checks that actually earn their place:

ParameterCheckReject as
Recipe / PPIDExists, enabled for this tool, revision matches the production ruleHCACK=3, or recipe-not-found
Carrier / slot idFormat, present at the expected E87 location, not already consumedCPACK=2
Port numberWithin range and currently availableCPACK=2
Numeric setpointRange, units, decimals, engineering limitCPACK=2

Do not silently default an important parameter. If the host omits a carrier id, don't inherit a stale internal value — return CPACK=1 and let the host see it forgot.

What S2F41 actually looks like on the wire

Code tables only get you so far; the header is faster to just look at. I opened a socket to the simulator's passive listener (:5501), completed Select, and sent one S2F41 with the body hand-encoded as SECS-II items.

TX  Select.req   00 00 00 0A 00 0B 00 00 00 01 00 00 02 01
RX  Select.rsp   00 00 00 0A 00 0B 00 00 00 02 00 00 02 01   (+3ms)

Byte 3 is 00 — Select Status 0, so we're SELECTED. Now the data message.

TX  S2F41  W=1   (44 bytes)
00 00 00 28 00 0B 82 29 00 00 00 00 02 02
01 02 41 05 53 54 41 52 54 01 01 01 02 41
04 50 50 49 44 41 09 45 54 43 48 5F 42 41
53 45

equipment-side RX decode:  len 40, sessionId 11, stream 2, wbit true,
                           function 41, ptype 0, stype 0, systemBytes 514

The first four bytes 00 00 00 28 are the length prefix: 0x28 = 40, which is header 10 + body 30. The prefix does not count itself, so 44 bytes actually crossed the socket. 00 0B is SessionID 11.

Header Byte 2 is 82. Top bit is the W-bit, bottom seven are the Stream — so stream 2, reply expected. Byte 3's 29 is decimal 41, Function 41. SType 00 makes it a data message rather than a control message, and PType 00 says the body is SECS-II encoded.

Those 30 body bytes are the item tree drawn above:

BytesMeaning
01 02L,2 — top-level list, two items
41 05 + 53 54 41 52 54A,5 START — RCMD
01 01L,1 — one parameter pair
01 02L,2 — the CPNAME/CPVAL pair
41 04 + 50 50 49 44A,4 PPID — CPNAME
41 09 + 45 54 43 48 5F 42 41 53 45A,9 ETCH_BASE — CPVAL

Reading a format byte is exactly what E5 specifies: the upper six bits are the format code, the lower two are how many length bytes follow. 0x41 = 0100 0001 → format code 16 (ASCII), one length byte. 0x01 = 0000 0001 → format code 0 (List), one length byte. So 41 05 reads "ASCII, 5 bytes" and 01 02 reads "list of two items."

And no S2F42 came back. I waited three seconds; nothing.

Be honest about why: this listener does not answer data messages at all. It handles SType 1 (Select.req), 5 (Linktest.req) and 9 (Separate.req) and nothing else. The silence is unimplemented behaviour, not a HCACK decision, so don't read this capture as evidence about how a tool handles commands. What it proves stops at the encoding.

What it does reproduce faithfully is the view from the host: the request went out, the equipment logged the RX, no reply came. The next section is about what not to do from exactly that position.

Retry: T3 expiring is a lost reply, not an ignored command

The HSMS reply timeout T3 fires when S2F42 never arrives. SEMI E37 mandates no default here: its timeout parameter table lists 45 s as a typical value, settable per link. Vendors ship the typical, so it behaves like a default in the field — but a tool that arrived with T3 = 30 s is conformant, and you cannot wave the standard at it. Write down both sides' actual settings before hookup.

T3 expiring is a lost reply, not necessarily a lost command — the tool may well have accepted and already started. Blindly resending START then fires a second process on the same lot.

  • Idempotent? A status query (S1F3) is safe to repeat; START is not.
  • Before resending, query and reconcile: S1F3 for the selected SVs, or read the PPExecName / active-command variable, and see what actually happened.
  • Use the enhanced remote command with a host-supplied DATAID so a duplicate is detectable.
  • Set a retry ceiling. When you hit it, raise an operator alarm instead of looping.

For motion, carrier transfer, recipe start and process commands, automatic blind retry is precisely the thing that turns one dropped packet into a double-processed lot.

Prove the reject path on purpose

Testing only valid commands leaves the entire reject path unproven — and the reject path is the half that pages you. Run these against a simulator, dry-run, or a safe idle state; a negative test must never fire real motion:

  1. ONLINE/LOCAL, then send a command → expect HCACK=2.
  2. START while EXECUTING → HCACK=2, or 5 if already in the requested state.
  3. Unknown PPID → HCACK=3 or recipe-not-found.
  4. Out-of-range numeric CPVAL → HCACK=3 with CPACK=2.
  5. Missing required CPNAME → HCACK=3 with CPACK=1.
  6. Valid command, then drop the HSMS link before the completion CEID — confirm the host reconciles instead of assuming failure.
  7. Same command twice → confirm duplicate handling.
  8. Interlock or alarm active → HCACK=2.

What belongs on the host screen

  • GEM communication state (E37 selected or not) and control state — ONLINE/REMOTE vs LOCAL
  • Equipment process state (E30 processing model)
  • Active alarm summary (ALID)
  • Active control job, process job, carrier, and PPID (E94 / E40 / E87)
  • Command in progress and the last HCACK returned

Most "failures" here aren't protocol faults. The tool is sitting in a state where the command is illegal and nothing on the host says so.

Before handover, capture one message trace per command showing S2F41 → S2F42 → the completion CEID, with the equipment state and the MES record beside it. Then do the same for the reject cases. If you can't produce that trace for a wrong-state or bad-parameter command, the reject path isn't proven — which means the part most likely to page you at 3am is the part you never tested.

If you want to check how your own driver assembles S2F41 before you get near a tool, open a socket to the SECS/GEM simulator and reproduce the capture above. It will tell you whether RCMD and your CPNAME/CPVAL pairs land where you think they do and whether the format bytes are right. It will not tell you anything about HCACK. That part is the tool's.