PinFinder.mesa - Tool to help find out which pin is connected to what
channel in the Dolphin chip tester.
last edited by McCreight, January 19, 1984 12:05 pm

DIRECTORY
ChipTest,
Commander,
CommandTool,
IO,
Process,
ProcessExtras;
PinFinder: CEDAR PROGRAM IMPORTS ChipTest, Commander, CommandTool, IO, Process, ProcessExtras =
BEGIN
tester: ChipTest.Tester;
FindShort: PROC RETURNS [found: BOOLEANFALSE, p1, p2: ChipTest.Channel ← 0] =
BEGIN OPEN ChipTest;
If p1 and p2 exist, then their representations differ in some bit position. This algorithm cycles through the bits in the representation of pin number, searching for some group of pins that causes a change in some other group of pins. As soon as this happens, we can identify the changees, and then turn the tables to find the changers.
d: RWChannelVecRef = NEW[ChannelVec];
FindHits: PROC RETURNS [count: NAT ← 0, aHit: Channel ← 0] =
BEGIN
hits: ChannelVec;
input: ChannelVecRef;
[] ← tester.PutBBuf[trues];
[] ← tester.PutABuf[falses];
tester.Step[];
tester.Step[];
input ← tester.GetIBuf[];
FOR j: Channel IN [FIRST[Channel]..LAST[Channel]] DO
hits[j] ← d[j] AND NOT input[j];
ENDLOOP;
[] ← tester.PutABuf[trues];
tester.Step[];
tester.Step[];
input ← tester.GetIBuf[];
FOR j: Channel IN [FIRST[Channel]..LAST[Channel]] DO
IF hits[j] AND d[j] AND input[j] THEN {aHit ← j; count ← count+1};
ENDLOOP;
END;
FOR delta: NAT ← 1, delta+delta WHILE delta<=LAST[Channel] DO
hitCount: NAT;
FOR j: Channel IN [FIRST[Channel]..LAST[Channel]] DO
d[j] ← ((j MOD 2*delta)<delta);
ENDLOOP;
[] ← tester.PutDisables[d];
[hitCount, p1] ← FindHits[];
SELECT hitCount FROM
>1 => {[] ← tester.PutDisables[trues]; RETURN};
=1 =>
BEGIN
FOR j: Channel IN [FIRST[Channel]..LAST[Channel]] DO
d[j] ← (j#p1);
ENDLOOP;
[] ← tester.PutDisables[d];
[hitCount, p2] ← FindHits[];
[] ← tester.PutDisables[trues];
found ← hitCount=1;
END;
ENDCASE => NULL;
ENDLOOP;
[] ← tester.PutDisables[trues];
END;
FindGround: PROC RETURNS [count: NAT ← 0, p: ChipTest.Channel ← 0] =
BEGIN OPEN ChipTest;
trues: ChannelVecRef = NEW[ChannelVec ← ALL[TRUE]];
falses: ChannelVecRef = NEW[ChannelVec ← ALL[FALSE]];
input: ChannelVecRef;
[] ← tester.PutDisables[trues];
tester.Step[];
tester.Step[];
input ← tester.GetIBuf[];
FOR j: Channel IN [FIRST[Channel]..LAST[Channel]] DO
IF NOT input[j] THEN {p ← j; count ← count+1};
ENDLOOP;
END;
SetTester: PROC [cmd: Commander.Handle] =
BEGIN
args: CommandTool.ArgumentVector = CommandTool.Parse[cmd: cmd];
tester ← ChipTest.OpenTester[(IF args.argc<2 THEN "" ELSE args[1])];
END;
WatchGround: Commander.CommandProc =
BEGIN
args: CommandTool.ArgumentVector = CommandTool.Parse[cmd: cmd];
in: IO.STREAM ← cmd.in;
out: IO.STREAM ← cmd.out;
oldCount: NAT;
oldP: ChipTest.Channel;
SetTester[cmd];
FOR pass: INT ← 0, 1 DO
count: NAT;
p: ChipTest.Channel;
ProcessExtras.CheckForAbort[ ! ABORTED => EXIT ];
tester.Initialize[]; -- in case of power off/on cycle
[count: count, p: p] ← FindGround[];
SELECT count FROM
0 =>
IF pass<1 OR oldCount#0 THEN
out.PutF["\nNo pin is grounded."];
1 =>
IF pass<1 OR oldCount#1 OR oldP#p THEN
out.PutF["\nPin %d is grounded.", IO.int[p]];
ENDCASE =>
IF pass<1 OR oldCount#count OR oldP#p THEN
out.PutF["\nPin %d and %d others are grounded.", IO.int[p], IO.int[count-1]];
oldCount ← count;
oldP ← p;
Process.Pause[ticks: Process.MsecToTicks[1000] ! ABORTED => EXIT ];
ENDLOOP;
out.PutF["\n"];
END;
StepLoop: Commander.CommandProc =
BEGIN
trues: ChipTest.ChannelVecRef = NEW[ChipTest.ChannelVec ← ALL[TRUE]];
falses: ChipTest.ChannelVecRef = NEW[ChipTest.ChannelVec ← ALL[FALSE]];
SetTester[cmd];
DO
ProcessExtras.CheckForAbort[ ! ABORTED => EXIT ];
tester.Initialize[]; -- in case of power off/on cycle
tester.PutABDelay[0];
tester.PutAIDelay[0];
[] ← tester.PutDisables[falses];
[] ← tester.PutABuf[trues];
[] ← tester.PutBBuf[trues];
tester.Step[];
[] ← tester.PutBBuf[falses];
tester.Step[];
[] ← tester.PutABuf[falses];
tester.Step[];
[] ← tester.PutBBuf[trues];
tester.Step[];
Process.Yield[];
ENDLOOP;
END;
TestTester: Commander.CommandProc =
BEGIN
trues: ChipTest.ChannelVecRef = NEW[ChipTest.ChannelVec ← ALL[TRUE]];
falses: ChipTest.ChannelVecRef = NEW[ChipTest.ChannelVec ← ALL[FALSE]];
a: ChipTest.RWChannelVecRef = NEW[ChipTest.ChannelVec ← ALL[FALSE]];
b: ChipTest.RWChannelVecRef = NEW[ChipTest.ChannelVec ← ALL[FALSE]];
m: ChipTest.RWChannelVecRef = NEW[ChipTest.ChannelVec ← ALL[FALSE]];
e: ChipTest.RWChannelVecRef = NEW[ChipTest.ChannelVec ← ALL[FALSE]];
SetTester[cmd];
FOR i: ChipTest.Channel ← 0, (i+1) MOD (LAST[ChipTest.Channel]+1) DO
Failure: PROC [expected, was: ChipTest.ChannelVecRef] =
{cmd.out.PutF["{%g=>%g}", IO.bool[expected[i]], IO.bool[was[i]]]};
ProcessExtras.CheckForAbort[ ! ABORTED => EXIT ];
tester.Initialize[]; -- in case of power off/on cycle
tester.PutABDelay[0];
tester.PutAIDelay[100];
[] ← tester.PutDisables[falses];
m[i] ← TRUE;
a[i] ← b[i] ← FALSE;
e[i] ← a[i]=b[i];
[] ← tester.PutABuf[a];
[] ← tester.PutBBuf[b];
tester.Step[];
[] ← tester.CheckI[e, m ! ChipTest.CheckFailure => {Failure[expected, was]; CONTINUE}];
b[i] ← TRUE;
e[i] ← a[i]=b[i];
[] ← tester.PutABuf[a];
[] ← tester.PutBBuf[b];
tester.Step[];
[] ← tester.CheckI[e, m ! ChipTest.CheckFailure => {Failure[expected, was]; CONTINUE}];
a[i] ← TRUE;
b[i] ← FALSE;
e[i] ← a[i]=b[i];
[] ← tester.PutABuf[a];
[] ← tester.PutBBuf[b];
tester.Step[];
[] ← tester.CheckI[e, m ! ChipTest.CheckFailure => {Failure[expected, was]; CONTINUE}];
b[i] ← TRUE;
e[i] ← a[i]=b[i];
[] ← tester.PutABuf[a];
[] ← tester.PutBBuf[b];
tester.Step[];
[] ← tester.CheckI[e, m ! ChipTest.CheckFailure => {Failure[expected, was]; CONTINUE}];
m[i] ← FALSE;
cmd.out.PutF[".%d", IO.int[i]];
Process.Yield[];
ENDLOOP;
END;
Commander.Register[key: "WatchGround", proc: WatchGround, doc: "Watches for grounded pins on Dolphin IC tester"];
Commander.Register[key: "StepLoop", proc: StepLoop, doc: "Exercises Dolphin IC tester so you can watch it with a 'scope"];
Commander.Register[key: "TestTester", proc: TestTester, doc: "Ensures that tester can control and sense pins"];
END.