(***************************************************************************)
(*                                                                         *)
(*                      BURR-BROWN CORPORATION                             *)
(*                                                                         *)
(*                    Application Bulletin AB-135                          *)
(*                                                                         *)
(***************************************************************************)
(*                                                                         *)
(*                      DDC112 Test Mode Program                           *)
(*                     Written in Turbo Pascal 7.0                         *)
(*                                                                         *)
(*    This program is designed to illustrate use of the DDC112's           *)
(*  test mode.  This program requires the DDC112 to be connected to the    *)
(*  DDC112 Evaluation Fixture DEM-DDC112U-C.  See AB-125 for more info     *)
(*  on the Evaluation Fixture.                                             *)
(*                                                                         *)
(*    The user can program the # of averages/reading, range,               *)
(*  Tint and # of test packets from the menu.  A single reading can be     *)
(*  retrieved or a complete measurement of the DDC112's linearity can be   *)
(*  taken.  The results of the linearity measurement are saved to a file   *)
(*                                                                         *)
(*  Created by Jim Todsen 5/20/98                                          *)
(*                                                                         *)
(***************************************************************************)
(*{$R-,S-}*)
{$A+,B-,E+,F+,G-,I+,L-,N+,O+,R+,S+,V-,X+}

program DDC112TestMode;

uses  Dos,CRT,Strings;

type
  Real4by1 = array[1..4] of real;   {used to store 1a,1b,2a,2b data}
                                    {1-->1a, 2-->2a, 3-->1b, 4-->2b}
var
  Range 		    : longint;
  Tint                      : real;
  Nt                        : longint;
  Tpck                      : longint;
  PCPort                    : longint;
  pPrintPort                : ^word;
  readdr, wraddr, strbaddr  : word;
  DataCkCode		    : word;
  SysCkCode                 : word;
  Ctrl1Code, Ctrl2Code      : word;
  DXmitDelayCode            : word;
  UserDDCCode               : word;
  Yave, Yrms                : Real4by1;

{***************************************************************************}
procedure badBeep;
{***************************************************************************}
begin
  sound(100);
  delay(200);
  nosound;
end;

{***************************************************************************}
procedure goodBeep;
{***************************************************************************}
begin
  sound(300);
  delay(50);
  nosound;
end;

{***************************************************************************}
procedure xilinxWrite(XilinxAddr, XilinxData : Byte);
{***************************************************************************}
{Write data to a specified address on the DDC112 Evaluation Fixture}
begin
  PORT[wraddr] := $7F AND XilinxAddr;
  Delay(2);
  PORT[strbaddr] := 1;
  Delay(1);
  PORT[strbaddr] := 0;
  Delay(1);
  PORT[wraddr] := $80 OR XilinxData;
  Delay(2);
  PORT[strbaddr] := 1;
  Delay(1);
  PORT[strbaddr] := 0;
  Delay(1);
end;


{***************************************************************************}
procedure setRange(newRange: word);
{***************************************************************************}
{set the DDC112 range}
begin
  writeln(' setting Range = ',newRange);
  Ctrl1Code := Ctrl1Code AND $78;
  Ctrl1Code := Ctrl1Code OR newRange;
  xilinxWrite(6,Ctrl1Code);
  delay(1000);  {wait for settling after change}
end;


{***************************************************************************}
procedure setTint(var newTint: real) ;
{***************************************************************************}
{Set the DDC112 Integration Time}
var
  IntCountCode  : longint;
begin
  if newTint > 1500000 then newTint := 1500000;
  IntCountCode := round(newTint*10)-1;                           {10 MHz CLK}
  writeln(' setting Tint = ',newTint:7:1);
  xilinxWrite(7,(Ctrl2Code AND $7E));                             {hold conv}
  Delay(1000);                               {wait to insure CONV is stopped}
  xilinxWrite(5,(IntCountCode AND $7F));
  xilinxWrite(4,((IntCountCode SHR 7)  AND $7F));
  xilinxWrite(3,((IntCountCode SHR 14) AND $7F));
  xilinxWrite(2,((IntCountCode SHR 21) AND $07));
  xilinxWrite(7,(Ctrl2Code OR $1));                            {release conv}
end;


{***************************************************************************}
procedure setTstPckts(NumPckt: longint);
{***************************************************************************}
{Set the # of Test Packets dumped to the DDC112 each integration}
begin
  if NumPckt > 0 then
  begin
    Ctrl1Code := Ctrl1Code OR $8;         {Test ON}
    xilinxWrite(6,Ctrl1Code);
    if NumPckt = 1 then xilinxWrite(11,127) {all 1's = 1 packet}
    else xilinxWrite(11,(NumPckt-2));
  end
  else
  begin
    Ctrl1Code := Ctrl1Code AND $F7; {Test OFF}
    xilinxWrite(6, (Ctrl1Code));
  end;
  Delay(1000);    {settling time after change}
end;


{***************************************************************************}
procedure setPCport(PCport: word);
{***************************************************************************}
{set the address of the PC's parallel port used for the Evaluation Fixture}
begin
  if PCPort = 1 then pPrintPort := Ptr($40,$08)
  else pPrintPort := Ptr($40,$0A);
  wraddr := pPrintPort^;
  readdr := wraddr + 1;
  strbaddr := wraddr + 2;
  PORT[strbaddr] := 0;     {init Strobe at 0 (really, 1 out)}
end;


{***************************************************************************}
procedure xilinxRefresh;
{***************************************************************************}
{Refresh the Xilinx FPGAs on the Evaluation Fixture}
begin
  PORT[strbaddr] := 0;    {init port strobe high}
  Delay(1);
  xilinxWrite(0, DataCkCode);
  xilinxWrite(1, SysCkCode);
  xilinxWrite(6, Ctrl1Code);
  XilinxWrite(7, Ctrl2Code);
  xilinxWrite(8, ((DXmitDelayCode AND $180) SHR 7));
  xilinxWrite(9, ((DXmitDelayCode AND $7F)));
  xilinxWrite(10, (UserDDCCode SHL 1));
  setRange(Range);
  setTint(Tint);
  setTstPckts(TPck);
  goodBeep;
end;


{***************************************************************************}
procedure getInt(descrip: string; Min, Max: longint;
                        var Value: longint; var Err: boolean);
{***************************************************************************}
{Get an INTEGER value from the user}
var
userinput  : string[25];
check      : integer;
temp       : longint;

begin
  Err := true;
  ClrScr;
  writeln;
  writeln(' The current ',descrip,' is: ',Value);
  writeln;
  writeln('  Enter the new ',descrip,':');
  readln(userinput);
  if userinput = 'x' then exit;
  if userinput = 'X' then exit;
  if userinput = '' then exit;
  val(userinput,temp,check);
  if check <> 0 then
  begin
    badBeep;
    writeln(' *** Invalid ',descrip);
    writeln;
    delay(1000);
    exit;
  end
  else
  begin
    if (temp < min) or (temp > max) then
    begin
      badBeep;
      writeln;
      writeln(' *** Invalid ',descrip);
      writeln;
      delay(500);
      exit;
    end
    else
    begin
      Value := temp;
      Err := false;
    end;
  end;
end;


{***************************************************************************}
procedure getReal(descrip: string; Min, Max: longint;
                        var Value: real; var Err: boolean);
{***************************************************************************}
{Get a REAL value from the user}
var
userinput  : string[25];
check      : integer;
temp       : real;

begin
  Err := true;
  ClrScr;
  writeln;
  writeln(' The current ',descrip,' is: ',Value:9:3);
  writeln;
  writeln('  Enter the new ',descrip,':');
  readln(userinput);
  if userinput = 'x' then exit;
  if userinput = 'X' then exit;
  if userinput = ''  then exit;
  val(userinput,temp,check);
  if check <> 0 then
  begin
    badBeep;
    writeln(' *** Invalid ',descrip);
    writeln;
    delay(500);
    exit;
  end
  else
  begin
    if (temp < min) or (temp > max) then
    begin
      badBeep;
      writeln;
      writeln(' *** Invalid ',descrip);
      writeln;
      delay(1000);
      exit;
    end
    else
    begin
      Value := temp;
      Err := false;
    end;
  end;
end;


{***************************************************************************}
procedure readData(var DRdError: Boolean);
{***************************************************************************}
{Readback "Nt" points from Evaluation Fixture; find Yave, Yrms, return status}
Var
  FNum, N                             : longint;    { final number }
  BusyBit3, Loop                      : integer;    { data ready bit }
  Nib, D, SideRd                      : byte;
  PortDataRd                          : byte;
  Ysum, Ysumsq                        : array[1..4] of Extended;
  temp                                : extended;
  iRd, TRd, K, Count, DataTime, I, J  : word;
  FScale,DelTime                      : real;
  FirstTime                           : boolean;
  timereq, SampleTime                 : real;
  numTints                            : word;


begin
  write(' filling Demo Board memory...  ');
  FirstTime := true;    {flag to check for side A or B on first data point}

  if Tint < 479.4 then  {ncont mode}
  begin
    timereq := 1501*6*1/10 - Tint; {1501=min # of slowclks to finish ncont meas}
    numTints := trunc(timereq / Tint)+1;                    {# of tints skipped}
    if ((numTints MOD 2) <> 0) then numTints := numTints+1; {numTints must be even}
    SampleTime := Tint*(2+numTints);
  end   {cont}
  else SampleTime := Tint*2;

  I := 0;
  while I < round(Nt*1.4 + 50) do  {extra margin for safety}
  begin
    delay(round(sampleTime/1e3));
    if KeyPressed AND (ReadKey = Chr(27)) then
    begin
      goodBeep;
      I := round(Nt*1.4 + 50);
    end;
    I := I + 1;
  end;

  xilinxWrite(6, Ctrl1Code AND $5F);         {enable readback}

  {wait for PC Interface Board Data Valid}
  K := 0;
  DRdError := false;
  BusyBit3 := (PORT[readdr] AND $08) SHR 3;  {initialize bit 3}
  While (BusyBit3 <> 1) AND (K <= 20000) do
  begin
    BusyBit3 := (PORT[readdr] AND $08) SHR 3;
    inc(K);
    if (K mod 40) = 0 then delay(1);
    if K = 20000 then DRdError := true;
  end;
  if DRdError = true then
  begin
    badBeep;
    clrscr;
    writeln;
    writeln('  **** Data Retrieval Error ****');
    writeln;
    writeln('  Check the following:');
    writeln;
    writeln('    DDC112 securely in socket');
    writeln('    power supplies at 5V');
    writeln('    cables properly connected');
    writeln('    demo board "refreshed"');
    writeln('    PC port set correctly');
    writeln;
    writeln('  ******************************');
    writeln;
    writeln('   Hit ENTER to continue   ');
    readln;
    exit;
  end
  else
  begin
    FScale := $FFFFF-$1000; {fullscale range = all ones - offset}
    for D := 1 to 4 do
    begin
      Ysum[D]   := 0;
      Ysumsq[D] := 0;
    end;
    writeln('retrieving data...');
    for N := Nt-1 downto 0 do
    begin
      for D := 1 to 4 do
      begin
        TRd := N + Nt*(D-1);
        Fnum := 0;
        PortDataRd := $6F;         {decrement Xilinx RAM memory address}
        PORT[wraddr] := PortDataRd;
        PORT[strbaddr] := 1;
        PORT[strbaddr] := 0;
        PORT[strbaddr] := 1;
        PORT[strbaddr] := 0;
        {prepare for RAM memory address  (PortDataRd := $6F;)}
        for iRd := 1 to 6 do               {get 6 nibbles}
        begin
          PortDataRd := PortDataRd - $10;  {MSB, MSB-1,...,LSB nibble}
          PORT[wraddr] := PortDataRd;
          PORT[strbaddr] := 1;
          PORT[strbaddr] := 0;
          {wait for PC Interface Board Data Valid}
          K := 0;
          BusyBit3 := (PORT[readdr] AND $08) SHR 3;       {init bit 3}
          While (BusyBit3 <> 1) AND (K <= 20000) do
          begin
            BusyBit3 := (PORT[readdr] AND $08) SHR 3;
            inc(K);
            if (K mod 40) = 0 then delay(1);
            if K = 20000 then
            begin
              DRdError := true;
              N := 0;
            end;
          end;
          nib := ((PORT[readdr] XOR $80) AND $F0) SHR 4;
               {XOR inverts bit 7 (-busy), AND F0 gets rid of 4 lower bits,
               shift right puts the data bits in lower nibble}
          if iRd = 1 then
            SideRd := ((nib AND $4) Xor $4) SHR 2;    {bit3 lo ==> sideA}
          Fnum := Fnum SHL 4;
          FNum := Fnum OR nib;               {Add nibble to final number}
        end;

        if FirstTime then
        begin
          if SideRd = 0 then FirstTime := false {first point is correct side}
          else
          begin
            FirstTime := false;
            for count := 1 to ((UserDDCCode-1)*2 + 1)  do  {read & throw away pts}
            begin
              PortDataRd := $6F;             {decrement Xilinx RAM Memory Address}
              PORT[wraddr] := PortDataRd;
              PORT[strbaddr] := 1;
              PORT[strbaddr] := 0;
              PORT[strbaddr] := 1;
              PORT[strbaddr] := 0;
              {prepare for RAM memory address  (PortDataRd := $6F;)}
              for iRd := 1 to 6 do                   {get 6 nibbles}
              begin
                PortDataRd := PortDataRd - $10;  {MSB, MSB-1,...,LSB nibble}
                PORT[wraddr] := PortDataRd;
                PORT[strbaddr] := 1;
                PORT[strbaddr] := 0;
                {wait For PC Interface Board DValid}
                K := 0;
                BusyBit3 := (PORT[readdr] AND $08) SHR 3;       {init bit 3}
                While (BusyBit3 <> 1) AND (K <= 20000) do
                begin
                  BusyBit3 := (PORT[readdr] AND $08) SHR 3;
                  inc(K);
                  if (K mod 40) = 0 then delay(1);
                  if K = 20000 then
                  begin
                    DRdError := true;
                    N := 0;
                  end;
                end;
              end;
            end;
            Fnum := 0;
            PortDataRd := $6F;         {decrement Xilinx RAM Memory Address}
            PORT[wraddr] := PortDataRd;
            PORT[strbaddr] := 1;
            PORT[strbaddr] := 0;
            PORT[strbaddr] := 1;
            PORT[strbaddr] := 0;
            {prepare for RAM memory address  (PortDataRd := $6F;)}
            for iRd := 1 to 6 do                   {get 6 nibbles}
            begin
              PortDataRd := PortDataRd - $10;    {MSB, MSB-1,...,LSB nibble}
              PORT[wraddr] := PortDataRd;
              PORT[strbaddr] := 1;
              PORT[strbaddr] := 0;
             {wait for PC Interface Board Data Valid}
              K := 0;
              BusyBit3 := (PORT[readdr] AND $08) SHR 3;         {init bit 3}
              While (BusyBit3 <> 1) AND (K <= 20000) do
              begin
                BusyBit3 := (PORT[readdr] AND $08) SHR 3;
                inc(K);
                if (K mod 40) = 0 then delay(1);
                if K = 20000 then
                begin
                  DRdError := true;
                  N := 0;
                end;
              end;
              nib := ((PORT[readdr] XOR $80) AND $F0) SHR 4;
               {XOR inverts bit 7 (-busy), AND F0 gets rid of 4 lower bits,
                shift right puts the data bits in lower nibble}
              if iRd = 1 then
                SideRd := ((nib AND $4) Xor $4) SHR 2;   {bit3 lo ==> sideA}
              Fnum := Fnum SHL 4;
              FNum := Fnum OR nib;              {add nibble to final number}
            end;
          end;
        end;

        Fnum := (FNum AND $000FFFFF);  {set bits 31-21 := 0}
        Fnum := Fnum - $1000;          {subtract offset}
        Ysum[D] := Ysum[D] + Fnum;
        temp := Fnum;
        temp := temp * Fnum;
        Ysumsq[D] := Ysumsq[D] + Temp;

      end;
     end;
    for D := 1 to 4 do
    begin
      Yave[D] := Ysum[D]/(Nt*FScale);
      temp := Nt*Ysumsq[D]-(Ysum[D]*Ysum[D]);
      Yrms[D] := Sqrt(abs(temp)/(Nt*(Nt-1)))/Fscale;
      Yrms[D] := Yrms[D] * 1e6;      {convert to ppm}
    end;
  end;

  xilinxWrite(6,Ctrl1Code OR $20);   {enable write to RAM}
end;


{***************************************************************************}
procedure retrieveData(var err: boolean);
{***************************************************************************}
{Call readData then display results}
begin
  readData(err);
  if err = false then
  begin
    ClrScr;
    writeln;
    writeln(' # of pts = ',Nt,'   Range = ',Range,'   Tint = ',Tint:8:1, '  Test pkts = ',TPck);
    writeln;
    writeln('        average    rms noise');
    writeln(' 1A: ',Yave[1]:11:7,'  ',Yrms[1]:6:2,' ppm');
    writeln(' 2A: ',Yave[2]:11:7,'  ',Yrms[2]:6:2,' ppm');
    writeln(' 1B: ',Yave[3]:11:7,'  ',Yrms[3]:6:2,' ppm');
    writeln(' 2B: ',Yave[4]:11:7,'  ',Yrms[4]:6:2,' ppm');
  end;
end;


{***************************************************************************}
procedure TestModeLinearity;
{***************************************************************************}
{Measure linearity of the DDC112's Test Mode}
{1st take 1 reading.  Use results to determine # of steps to fullscale.}
{Fit data with endpoint line and report max deviation from that line.}
var
  n,i            : integer;
  err            : boolean;
  userName       : string[8];
  fileName       : string[12];
  F1             : text;
  tpacket        : real;
  steps          : word;
  Tdat           : array[1..4,0..100] of real;  {holds data for lin fit}
  m,b            : real;
  INLpt, INLmax  : real;
  INL            : array[1..4] of real;

begin
  ClrScr;
  if Nt < 10 then
  begin
    writeln;
    writeln('***  The number of points / reading is low ***');
    writeln;
    writeln('     Increase the number for better results   ');
    badBeep;
    getInt('# of points',1,10000,Nt,err);
  end;

  writeln;
  writeln('Enter a file name for Test Mode Linearity data (max 8 characters)');
  readln(userName);
  writeln;
  fileName := userName + '.DAT';
  assign(F1,fileName);
  delay(1);
  {$I-} rewrite(F1); {$I+}
  if ioresult <> 0 then
  begin
    writeln('');
    writeln(' *** File I/O Problem, try a new name...');
    delay(400);
    badBeep;
    exit;
  end;

  setTstPckts(1);              {set test pckts = 1 & collect 1st data}
  writeln(' collecting test data 1');
  readData(err);
  if err = false then
  begin                        {use 1st data pt to calc # steps required}
    for n := 1 to 4 do Tdat[n,1] := Yave[n];
    tpacket := (Yave[1])*100;  {calc packet size}
    writeln;
    writeln('*** Each test packet is ',tpacket:4:1,' % of full scale ***');
    steps := trunc(1/Yave[1]); {calc # of steps for fullscale}
    if steps > (trunc(Tint/5.4)) then
    begin
      steps := trunc(Tint/5.4);
      writeln;
      writeln('***********************************************');
      writeln('Test Mode will not be able to reach full scale');
      writeln('with current Tint.  Increasing Tint will allow');
      writeln('more test packets dumps during the integration.');
      writeln('***********************************************');
      badBeep;
    end;
  end
  else exit;

  for i := 2 to steps do       {collect rest of data}
  begin
    writeln;
    writeln(' collecting test data ',i,' out of ',steps);
    setTstPckts(i);
    readData(err);
    if err = true  then exit;
    for n := 1 to 4 do Tdat[n,i] := Yave[n];
  end;
  setTstPckts(Tpck);           {restore user Test Package setting}

  ClrScr;
  writeln;
  writeln('   Linearity Results: Endpoint Fit');
  writeln('   (max deviation from endpoint line)');
  writeln;
  for n := 1 to 4 do           {fit linearity}
  begin
    b := Tdat[n,1];            {y = mx + b}
    m := (Tdat[n,steps] - Tdat[n,1])/(steps-1);
    INLmax := 0;
    for i := 2 to (steps-1) do {INL for i=1 & steps =0 for endpoint fit}
    begin
      INLpt := Abs(Tdat[n,i] - (m*(i-1) + b));
      if INLpt > INLmax then INLmax := INLpt;
     end;
    INL[n] := 1e6* INLmax ;    {convert to ppm}
    case n of
      1: writeln('  INL for 1a = ',INL[1]:6:1,' ppm');
      2: writeln('  INL for 2a = ',INL[2]:6:1,' ppm');
      3: writeln('  INL for 1b = ',INL[3]:6:1,' ppm');
      4: writeln('  INL for 2b = ',INL[4]:6:1,' ppm');
    end;
  end;

  writeln(F1,'        Burr-Brown Corporation        ');
  writeln(F1,'      Application Bulletin AB-135     ');
  writeln(F1,'DDC112 Test Mode linearity measurement');
  writeln(F1);
  writeln(F1,'# of averages/readings = ',Nt);
  writeln(F1,'Range = ',Range);
  writeln(F1,'Tint = ',Tint:7:1);
  writeln(F1);
  writeln(F1,'# Test');
  writeln(F1,'Packets     1a ave      2a ave      1b ave      2b ave');
  for i := 1 to steps do
  writeln(F1,i:3,'     ',Tdat[1,i]:11:6,' ',Tdat[2,i]:11:6,' ',Tdat[3,i]:11:6,' ',Tdat[4,i]:11:6);
  writeln(F1);
  writeln(F1,' Endpoint Fit');
  writeln(F1,' INL(ppm): ',INL[1]:8:1, INL[2]:12:1, INL[3]:12:1, INL[4]:12:1);
  close(F1);

  goodBeep;
  writeln;
  writeln('   Hit ENTER to continue...');
  readln;
end;


{***************************************************************************}
{***************************************************************************}
{Main}
{***************************************************************************}
{***************************************************************************}
var
  userinput     : string[10];
  goodbye,done  : boolean;
  err           : boolean;
  choice        : word;
  check         : integer;
  minTint       : real;

begin
  Range := 5;
  Tint  := 500;
  Nt    := 500;
  TPck  := 1;
  PCPort         := 1;
  DataCkCode     := 2;
  SysCkCode      := 0;
  DXmitDelayCode := 0;
  UserDDCCode    := 1;
  Ctrl1Code      := $20;           {initially Read, internal DCLk}
  Ctrl2Code      := 1;             {demo bd CONV}
  pPrintPort     := Ptr($40,$08);  {default: PC port=1}
  wraddr         := pPrintPort^;
  readdr         := wraddr + 1;
  strbaddr       := wraddr + 2;
  PORT[strbaddr] := 0;             {init Strobe at 0 (really, 1 out)}

  xilinxRefresh;
  ClrScr;
  goodbye := false;
  while (goodbye <> true) do
  begin
    ClrScr;
    writeln;
    writeln('  ---------------------------------------');
    writeln('  |        Burr-Brown Corporation       |');
    writeln('  |      Application Bulletin AB-135    |');
    writeln('  |                                     |');
    writeln('  | DDC112 Test Mode Evaluation Program |');
    writeln('  ---------------------------------------');
    writeln;
    writeln('   # points/reading = ',Nt);
    writeln('              Range = ',Range);
    writeln('               Tint = ',Tint:7:1);
    writeln('     # test packets = ',TPck);
    writeln;
    writeln;
    writeln('  =========================== ');
    writeln('  Choose one of the following ');
    writeln('  =========================== ');
    writeln;
    writeln('   1) Refresh Demo Board');
    writeln;
    writeln('   2) Set # points averaged/reading');
    writeln('   3) Set Range');
    writeln('   4) Set Tint');
    writeln('   5) Set # of Test Mode packets');
    writeln('   6) Set PC port');
    writeln;
    writeln('   7) Take single reading');
    writeln('   8) Measure Linearity of Test Mode');
    writeln;
    writeln('   9) exit program');
    writeln;
    readln(userinput);
    val(userinput,choice,check);
    if check <> 0 then badBeep
    else
    begin
      if (choice < 0) or (choice > 9) then badBeep
      else
        case choice of
          1: begin
               writeln;
               writeln('Refreshing Demo Board...');
               xilinxRefresh;
             end;

          2: getInt('# of points',1,10000,Nt,err);

          3: begin
               getInt('Range',0,7,Range,err);
               if err = false then setRange(Range);
             end;

          4: begin
	       getReal('Tint',0,1500000,Tint,err);
               if err = false then setTint(Tint);
             end;

          5: begin
	       getInt('Test Mode Packets',0,128,TPck,err);
               if err = false then
               begin
                 if TPck > Trunc(Tint/5.4) then   {allow 5.4us per packet}
                 begin
                   writeln;
                   writeln('*************************************************');
                   writeln('  # of Test Packets is too high for current Tint.');
                   minTint := TPck*5.4;
                   writeln('  Tint must be > ',minTint:7:1,' us for ',TPck,' packets.');
                   TPck := Trunc(Tint/5.4);
                   writeln('  Setting # of Test Packets to ',TPck);
                   writeln('*************************************************');
                   writeln;
                   writeln('     Hit ENTER to continue...');
                   BadBeep;
                   readln;
                  end;
                  setTstPckts(TPck);
                end;
             end;

          6: begin
               getInt('PC port',1,2,PCport,err);
               setPCport(PCport);
             end;

          7: begin
               done := false;
               while done = false do
               begin
                 retrieveData(err);
                 if err = true then done := true
                 else
                 begin
                   writeln;
                   writeln('  enter "r" to repeat measurement');
                   readln(userinput);
                   if (userinput <> 'r') AND (userinput <> 'R')
                   then done := true;
                 end;
               end;
             end;

          8: TestModeLinearity;

          9: goodbye := true;
        end;
    end;
  end;
end.
