-- WaferProberImpl.mesa
-- Access to Wafer Prober
DIRECTORY
Inline USING [LowHalf],
IODefs: FROM "IODefs" USING [
WriteChar, ReadChar, CR, LF, ControlE, ControlS, ControlQ, ControlR, ControlT,
ControlU, WriteString, WriteDecimal],
PupStream: FROM "PupStream" USING [
GetPupAddress, PupAddress, PupPackageDestroy, PupPackageMake, SecondsToTocks,
PupByteStreamCreate],
Storage USING [Words, FreeWords, String],
Stream: FROM "Stream" USING [
Handle, Delete, SetInputOptions, SendNow, Block, GetBlock, PutBlock, InputOptions,
CompletionCode, GetChar, PutChar, TimeOut],
String USING [
AppendChar, AppendSubString, AppendString, DeleteSubString, SubString,
EqualSubString, SubStringDescriptor, EquivalentString, WordsForString],
WaferProber;
WaferProberImpl: PROGRAM
IMPORTS Inline, IODefs, PupStream, Storage, Stream, String EXPORTS WaferProber
=
BEGIN OPEN IODefs, PupStream, Stream, String;
WaferProberObject: PUBLIC TYPE = RECORD[streamHandle: Stream.Handle, pupAddress: PupAddress, inBlock, outBlock: Block, buffer: STRING ← NIL];
Handle: TYPE = LONG POINTER TO WaferProberObject;
MyOptions: InputOptions = [terminateOnEndPhysicalRecord: TRUE, signalLongBlock: FALSE, signalShortBlock: TRUE, signalSSTChange: FALSE, signalEndOfStream: FALSE];
--
--
Open: PUBLIC PROCEDURE [name: STRING] RETURNS [h: Handle ← NIL] =
BEGIN
h ← Storage.Words[SIZE[WaferProberObject]];
h.buffer ← Storage.Words[WordsForString[256]];
h.buffer↑ ← [length: 0, maxlength: 256, text:];
h.inBlock.blockPointer ← @h.buffer.text;
h.inBlock.startIndex ← 0;
h.inBlock.stopIndexPlusOne ← h.buffer.maxlength;
h.outBlock.startIndex ← 0;
PupPackageMake;
GetPupAddress[Inline.LowHalf[@h.pupAddress], name];
h.streamHandle ← PupByteStreamCreate[h.pupAddress, SecondsToTocks[60]];
SetInputOptions[h.streamHandle, MyOptions];
RETURN[h]
END; -- Open
Close: PUBLIC PROCEDURE [ph: LONG POINTER TO Handle] =
BEGIN
h: Handle = ph↑;
Stream.Delete[h.streamHandle];
PupPackageDestroy;
ph↑ ← NIL;
Storage.FreeWords[h.buffer];
Storage.FreeWords[Inline.LowHalf[h]];
END; -- Close
Align: PUBLIC PROCEDURE [h: Handle] =
BEGIN
[] ← TalkToWaferProber[h, "AL*"];
END; -- Align
GetDeviceCoordinate: PUBLIC PROCEDURE [h: Handle] RETURNS [x, y: STRING ← NIL] =
BEGIN
response: STRING = TalkToWaferProber[h, "?DC*", FALSE];
ssd: SubStringDescriptor;
ss: SubString = @ssd;
IF response[0] = 'D AND response[1] = 'C THEN
{
indexSep: CARDINAL ← 0;
indexLast: CARDINAL ← 0;
FOR i: CARDINAL IN [0..response.length) DO
IF response[i] = '- THEN indexSep ← i;
IF response[i] = '* THEN indexLast ← i;
ENDLOOP;
x ← Storage.String[indexSep-2];
ssd ← [base: response, offset: 2, length: x.maxlength];
AppendSubString[x, ss];
y ← Storage.String[indexLast-(indexSep+1)];
ssd ← [base: response, offset: (indexSep+1), length: y.maxlength];
AppendSubString[y, ss];
}
ELSE {ERROR};
RETURN[x, y]
END; -- GetDeviceCoordinate
GoHide: PUBLIC PROCEDURE [h: Handle] =
BEGIN
[] ← TalkToWaferProber[h, "HI*"];
END; -- GoHide
GoHome: PUBLIC PROCEDURE [h: Handle] =
BEGIN
[] ← TalkToWaferProber[h, "HO*"];
END; -- GoHome
InitializeZ: PUBLIC PROCEDURE [h: Handle] =
BEGIN
[] ← TalkToWaferProber[h, "ZI*"];
END; -- InitializeZ
Load: PUBLIC PROCEDURE [h: Handle] =
BEGIN
[] ← TalkToWaferProber[h, "LD*"];
END; -- Load
SetDieSize: PUBLIC PROCEDURE [h: Handle, x, y: STRING] =
BEGIN
command: STRING = [128];
command.length ← 0;
AppendString[command, "DS"L];
AppendString[command, x];
AppendString[command, "-"L];
AppendString[command, y];
AppendString[command, "*"L];
[] ← TalkToWaferProber[h, command];
END; -- SetDieSize
Seek: PUBLIC PROCEDURE [h: Handle, x, y: STRING] =
BEGIN
command: STRING = [128];
command.length ← 0;
AppendString[command, "SK"L];
AppendString[command, x];
AppendString[command, "-"L];
AppendString[command, y];
AppendString[command, "*"L];
[] ← TalkToWaferProber[h, command];
END; -- Seek
SetDeviceCoordinate: PUBLIC PROCEDURE [h: Handle, x, y: STRING] =
BEGIN
command: STRING = [128];
command.length ← 0;
AppendString[command, "DC"L];
AppendString[command, x];
AppendString[command, "-"L];
AppendString[command, y];
AppendString[command, "*"L];
[] ← TalkToWaferProber[h, command];
END; -- SetDeviceCoordinate
ToggleZ: PUBLIC PROCEDURE [h: Handle] =
BEGIN
[] ← TalkToWaferProber[h, "ZM*"];
END; -- ToggleZ
--
--
--
TalkToWaferProber: PROCEDURE [h: Handle, DummyPointer: STRING, actionCompleteExpected: BOOLEAN ← TRUE]
RETURNS [NewPointer: STRING] =
BEGIN
Why: CompletionCode;
h.outBlock.blockPointer ← @DummyPointer.text;
h.outBlock.stopIndexPlusOne ← DummyPointer.length;
PutBlock[h.streamHandle, h.outBlock, FALSE];
SendNow[h.streamHandle];
[h.buffer.length, Why] ← GetBlock[h.streamHandle, h.inBlock!
TimeOut =>
BEGIN
WriteChar[CR];
WriteString["No response from LoGlas, it may be busy"];
WriteChar[CR];
WriteString["Try Again,Debugger,Quit?"];
SELECT ReadChar[] FROM
'T, 't => RETRY;
'C, 'c => CONTINUE;
'D, 'd => ERROR TimeOut[nextIndex];
'Q, 'q => BEGIN
WriteString["Will now close data base"];
WriteChar[CR];
--NoMoreWafers ← TRUE;
GOTO End;
END;
ENDCASE => ERROR;
END; ];
SELECT Why FROM
= normal => NULL;--WriteString["CompletionCode is Normal "];
= endRecord => NULL;--WriteString["CompletionCode is endRecord "];
= sstChange => WriteString["CompletionCode is sstChange "];
= endOfStream => WriteString["CompletionCode is endOfStream "];
ENDCASE => WriteString["CompletionCode Error "];
--WriteChar[CR];
SELECT h.buffer[h.buffer.length - 2] FROM
= ControlS => NULL;
= ControlQ =>
BEGIN
WriteString["On-Line mode Selected---"];
WriteString["Strike a key to continue"];
[] ← ReadChar[];
END;
= ControlR =>
BEGIN
WriteString["Off-Line mode Selected---"];
WriteString["Strike a key to continue"];
[] ← ReadChar[];
END;
= ControlT =>
BEGIN
WriteString["Repeat Transmission---"];
WriteString["Strike a key to continue"];
[] ← ReadChar[];
END;
= ControlU =>
BEGIN
WriteString["Data Not Acknowledged---"];
WriteString["Strike a key to continue"];
[] ← ReadChar[];
END;
ENDCASE; -- => WriteString["You must not have found the correct character"];
-- WriteChar[CR];
-- WriteString["Prober responds with "];
-- WriteString[h.buffer];
-- WriteChar[CR];
NewPointer ← h.buffer;
EXITS End => NULL;
END; -- TalkToWaferProber
CutOffRecord: SubStringDescriptor;
CutOff: SubString = @CutOffRecord;
PromptString: STRING = "COMMAND:";
PromptRecord: SubStringDescriptor ← [PromptString, 0, 8];
Prompt: SubString = @PromptRecord;
BREAKString: STRING = "*BREAK";
BREAKRecord: SubStringDescriptor ← [BREAKString, 0, 6];
BREAK: SubString = @BREAKRecord;
LineRecord: SubStringDescriptor;
LinePointer: SubString = @LineRecord;
CRLF: STRING ← [2];
ContE: STRING ← [1];
-- Mainline Statements Follow, Initialization only
AppendChar[CRLF, CR];
AppendChar[CRLF, LF];
AppendChar[ContE, ControlE];
END.-- WaferProberImpl