{*********************************************************}{   AP10PC.PAS                                            }{   by Miaochen Wu                                        }{                                                         }{   Accessing the ADS1210 Demo Board with Your PC         }{   Application Note AB-113                               }{   Burr-Brown Corp., 1997                                }{                                                         }{   Turbo Pascal 7.0                                      }{*********************************************************}program AP10PC;uses    CRT, DOS;const   MCwrite51            = $00;   MCretrieve           = $20;   MCwrite1210          = $40;   MCread1210           = $60;   MCreadback           = $80;   MCconvert            = $A0;   MCsync               = $C0;   MCpcgetl             = $E0;var   strbaddr             : Word;   wraddr               : Word;   rdaddr               : Word;   pPrintPort           : ^word;   RADSSetup            : Longint;   INSRegCode           : Byte;   CMRegCode            : Longint;   OCRegCode            : Longint;   FCRegCode            : Longint;   XAddr_DOR2           : Byte;   XAddr_DOR1           : Byte;   XAddr_DOR0           : Byte;   XAddr_INSR           : Byte;   XAddr_CMR3           : Byte;   XAddr_CMR2           : Byte;   XAddr_CMR1           : Byte;   XAddr_CMR0           : Byte;   XAddr_OCR2           : Byte;   XAddr_OCR1           : Byte;   XAddr_OCR0           : Byte;   XAddr_FCR2           : Byte;   XAddr_FCR1           : Byte;   XAddr_FCR0           : Byte;   XAddr_ADS            : Byte;   ADSID                : Byte;   XAddr_READADD0       : Byte;   XAddr_READADD1       : Byte;   XAddr_READADD2       : Byte;   Nbyte2x              : Byte;   INSRaddr             : Byte;   Readback             : Boolean;procedure ADSRback; forward;procedure ReadSetup(var SURdError : Boolean;          ADSSetupCode : longint); forward;procedure ReadData(Nt : longint; ConvertTime : Real;          var OldReadTime : Real; var DRdError : Boolean);          forward;procedure MC51write(MC51code : byte);var   busy         : Byte;   K            : Word;begin  { busy=H in board, busy7=L in code }  K :=0;  busy := PORT[rdaddr] AND $80;  while (busy <> $80) AND (K<=80000) do    begin    busy := PORT[rdaddr] AND $80;    inc(K);    end;  PORT[wraddr] := MC51code;  delay(1);  PORT[strbaddr] := 1;  delay(0);  PORT[strbaddr] := 0;  delay(1);  if K >= 80000 then    begin    sound(1000);    delay(200);    nosound;    writeln;    writeln('Program halted as System Setup Errors detected.');    writeln('Possible causes include: Power supply off, Bad cables,Program halted as System Setup Errors detected.');    writeln('Wrong PC Parallel Port, ADS1210 not installed.');    sound(1000);    delay(300);    nosound;    halt;    end;end;procedure revbit(revin : byte; var revcode : byte);var   i    : word;   j    : word;begin  revcode := 0;  j := 1;  for i := 0 to 7 do    begin    revcode := revcode SHL 1;    if revin AND j > 0 then    revcode := revcode + 1;    j := j SHL 1;    end;end;procedure Renew;type    NewCType    = array[1..3] of Byte;var   CMRbyte      : Byte;   OCRbyte      : Byte;   FCRbyte      : Byte;   revcode      : Byte;   CC           : Byte;   NewCode      : NewCType;begin    {Write CMR byte 3}    CMRbyte := ( CMRegCode SHR 24 ) AND $FF;    MC51write((MCwrite51 OR XAddr_CMR3));    revbit(CMRbyte,revcode);    MC51write(revcode);    {Write CMR byte 2}    CMRbyte := ( CMRegCode SHR 16 ) AND $FF;    MC51write((MCwrite51 OR XAddr_CMR2));    revbit(CMRbyte,revcode);    MC51write(revcode);    {Write CMR byte 1}    CMRbyte := ( CMRegCode SHR 8 ) AND $FF;    MC51write((MCwrite51 OR XAddr_CMR1));    revbit(CMRbyte,revcode);    MC51write(revcode);    {Write CMR byte 0}    CMRbyte := CMRegCode AND $FF;    MC51write((MCwrite51 OR XAddr_CMR0));    revbit(CMRbyte,revcode);    MC51write(revcode);    {Write INSR}    delay(100);    MC51write((MCwrite51 OR XAddr_INSR));    MC51write($64);    {Programming ADS1210}    MC51write(MCwrite1210);    {Write OCR}    delay(100);    OCRbyte := ( OCRegCode SHR 16 ) AND $FF;    MC51write((MCwrite51 OR XAddr_OCR2));    revbit(OCRbyte,revcode);    MC51write(revcode);    OCRbyte := ( OCRegCode SHR 8 ) AND $FF;    MC51write((MCwrite51 OR XAddr_OCR1));    revbit(OCRbyte,revcode);    MC51write(revcode);    OCRbyte := OCRegCode AND $FF;    MC51write((MCwrite51 OR XAddr_OCR0));    revbit(OCRbyte,revcode);    MC51write(revcode);    delay(100);    MC51write((MCwrite51 OR XAddr_INSR));    MC51write($48);    MC51write(MCwrite1210);    {Write FCR}    delay(100);    FCRbyte := ( FCRegCode SHR 16 ) AND $FF;    MC51write((MCwrite51 OR XAddr_FCR2));    revbit(FCRbyte,revcode);    MC51write(revcode);    FCRbyte := ( FCRegCode SHR 8 ) AND $FF;    MC51write((MCwrite51 OR XAddr_FCR1));    revbit(FCRbyte,revcode);    MC51write(revcode);    FCRbyte := FCRegCode AND $FF;    MC51write((MCwrite51 OR XAddr_FCR0));    revbit(FCRbyte,revcode);    MC51write(revcode);    delay(100);    MC51write((MCwrite51 OR XAddr_INSR));    MC51write($4C);    MC51write(MCwrite1210);    {Read back ADS1210}    NewCode[1] := $E4;    NewCode[2] := $C8;    NewCode[3] := $CC;    for CC := 1 to 3 do      begin      delay(100);      INSRegCode := NewCode[CC];      Nbyte2x := (INSRegCode AND $60) SHR 5;      Nbyte2x := Nbyte2x + 1;      Nbyte2x := Nbyte2x SHL 1;      INSRaddr := INSRegCode AND $1F;      MC51write((MCwrite51 OR XAddr_INSR));      MC51write(INSRegCode);      MC51write(MCread1210);      delay(100);      ReadBack := True;      ADSRBack;      end;end;procedure SetINSR;var   I            : Byte;begin  Nbyte2x := (INSRegCode AND $60) SHR 5;  Nbyte2x := Nbyte2x + 1;  Nbyte2x := Nbyte2x SHL 1;  INSRaddr := INSRegCode AND $1F;  MC51write((MCwrite51 OR XAddr_INSR));  MC51write(INSRegCode);  I := INSRegCode AND $80;  case I of    $00:  begin          if ((INSRaddr = $00) OR (INSRaddr = $01)          OR (INSRaddr = $02)) then            writeln('Don''t write data register. ')          else            MC51write(MCwrite1210);          end;    $80:  begin          MC51write(MCread1210);          ReadBack := True;          ADSRBack;          end;  end;end;procedure SetCMR;var  CMRbyte       : Byte;  revcode       : Byte;begin     {CMR Byte 3}     CMRbyte := ( CMRegCode SHR 24 ) AND $FF;     MC51write((MCwrite51 OR XAddr_CMR3));     revbit(CMRbyte,revcode);     MC51write(revcode);     {CMR Byte 2}     CMRbyte := ( CMRegCode SHR 16 ) AND $FF;     MC51write((MCwrite51 OR XAddr_CMR2));     revbit(CMRbyte,revcode);     MC51write(revcode);     {CMR Byte 1}     CMRbyte := ( CMRegCode SHR 8 ) AND $FF;     MC51write((MCwrite51 OR XAddr_CMR1));     revbit(CMRbyte,revcode);     MC51write(revcode);     {CMR Byte 0}     CMRbyte := CMRegCode AND $FF;     MC51write((MCwrite51 OR XAddr_CMR0));     revbit(CMRbyte,revcode);     MC51write(revcode);     { Setup for reading back }     INSRegCode := $64;     Nbyte2x := (INSRegCode AND $60) SHR 5;     Nbyte2x := Nbyte2x + 1;     Nbyte2x := Nbyte2x SHL 1;     INSRaddr := INSRegCode AND $1F;     Delay(10);     MC51write((MCwrite51 OR XAddr_INSR));     MC51write(INSRegCode);     MC51write(MCwrite1210);     delay(100);     INSRegCode := $E4;     MC51write((MCwrite51 OR XAddr_INSR));     MC51write(INSRegCode);     MC51write(MCread1210);     delay(100);     ReadBack := True;     ADSRback;end;procedure SetOCR;var  OCRByte       : Byte;  revcode       : Byte;begin     {OCR Byte 3}     OCRbyte := ( OCRegCode SHR 16 ) AND $FF;     MC51write((MCwrite51 OR XAddr_OCR2));     revbit(OCRbyte,revcode);     MC51write(revcode);     {OCR byte 2}     OCRbyte := ( OCRegCode SHR 8 ) AND $FF;     MC51write((MCwrite51 OR XAddr_OCR1));     revbit(OCRbyte,revcode);     MC51write(revcode);     {OCR byte 0}     OCRbyte := OCRegCode AND $FF;     MC51write((MCwrite51 OR XAddr_OCR0));     revbit(OCRbyte,revcode);     MC51write(revcode);     {Setup for reading back}     INSRegCode := $48;     Nbyte2x := (INSRegCode AND $60) SHR 5;     Nbyte2x := Nbyte2x + 1;     Nbyte2x := Nbyte2x SHL 1;     INSRaddr := INSRegCode AND $1F;     Delay(10);     MC51write((MCwrite51 OR XAddr_INSR));     MC51write(INSRegCode);     MC51write(MCwrite1210);     delay(100);     INSRegCode := $C8;     MC51write((MCwrite51 OR XAddr_INSR));     MC51write(INSRegCode);     MC51write(MCread1210);     delay(100);     ReadBack := True;     ADSRBack;end;procedure SetFCR;var  FCRbyte       : Byte;  revcode       : Byte;begin     {FCR Byte 2}     FCRbyte := ( FCRegCode SHR 16 ) AND $FF;     MC51write((MCwrite51 OR XAddr_FCR2));     revbit(FCRbyte,revcode);     MC51write(revcode);     {FCR byte 1}     FCRbyte := ( FCRegCode SHR 8 ) AND $FF;     MC51write((MCwrite51 OR XAddr_FCR1));     revbit(FCRbyte,revcode);     MC51write(revcode);     {FCR byte 0}     FCRbyte := FCRegCode AND $FF;     MC51write((MCwrite51 OR XAddr_FCR0));     revbit(FCRbyte,revcode);     MC51write(revcode);     {Setup for reading back}     INSRegCode := $4C;     Nbyte2x := (INSRegCode AND $60) SHR 5;     Nbyte2x := Nbyte2x + 1;     Nbyte2x := Nbyte2x SHL 1;     INSRaddr := INSRegCode AND $1F;     Delay(10);     MC51write((MCwrite51 OR XAddr_INSR));     MC51write(INSRegCode);     MC51write(MCwrite1210);     delay(100);     INSRegCode :=$CC;     MC51write((MCwrite51 OR XAddr_INSR));     MC51write(INSRegCode);     MC51write(MCread1210);     delay(100);     ReadBack := True;     ADSRBack;end;procedure ADSsync;begin     MC51write((MCwrite51 OR XAddr_ADS));     MC51write(ADSID);     MC51write(MCsync);end;procedure ADSRback;var  NRbackBit       : Byte;  Dbyte3          : Byte;  Dbyte2          : Byte;  Dbyte1          : Byte;  Dbyte0          : Byte;  coderev         : Byte;  RdError         : Boolean;  codetype        : string[4];begin  If (ReadBack = True) then    begin      case INSRaddr of        $04,$05,$06,$07:  begin                          codetype :='CMR';                          ReadSetup(RdError,CMRegCode);                          end;        $08,$09,$0A:      begin                          codetype := 'OCR';                          ReadSetup(RdError,OCRegCode);                          end;        $0C,$0D,$0E:      begin                          codetype := 'FCR';                          ReadSetup(RdError,FCRegCode);                          end;      else        RdError := True;      end;    end;  if (RdError = True) then    writeln('Setup Readback Error.')  else    writeln('The ' ,codetype, ' readback is  ', RADSSetup);end;procedure Retrieve;var  Hour          : Word;  Minute        : Word;  Second        : Word;  Sec100        : Word;  Nt            : longint;  RdError       : Boolean;  OldReadTime   : Real;  ConvertTime   : Real;begin  GetTime(Hour, Minute, Second, Sec100);  OldReadTime := 3600*Hour + 60*Minute + Second + Sec100 div 100;  ConvertTime := 0.01; {ADS1210 Data Rate = 100Hz}  Nt := 16; { Number of Data point }  Nbyte2x := 6;  ReadData(Nt, ConvertTime, OldReadTime, RdError);  if(RdError = True) then    writeln('Data Retrieval Error.');end;{Procedure ReadSetup reads back ADS1210 data }procedure ReadSetup(var SURdError : Boolean; ADSSetupCode : longint);var   FNum         : Longint;   readbkloop   : Longint;   BusyBit      : Byte;    { data ready bit }   nib          : Byte;    { nibble from MC51 }   iRd          : Word;   K            : Word;   coderev      : Byte;begin  SURdError := False;  Fnum := $FFFFFFFF;  if SURdError = False then    begin    readbkloop := 0;    WHILE ((FNUM AND $FFFFFFFF) <> (ADSSetupCode AND $FFFFFFFF))    AND (readbkloop < 1) DO      BEGIN      readbkloop := readbkloop + 1;      Fnum := 0;      for iRd := 1 to NByte2x do        begin        K :=0;        BusyBit := PORT[rdaddr] AND $80;        while (BusyBit <> $80) AND (K <= 200000)  do          begin          BusyBit := PORT[rdaddr] AND $80;          inc(K);          if (K mod 40) = 0 then delay(1);          if K = 200000 then SURdError := True;          end;        PORT[wraddr] := $80;        delay(1);        PORT[strbaddr] := 1;        delay(0);        PORT[strbaddr] := 0;        delay(1);        nib := (PORT[rdaddr] AND $78) SHL 1;        revbit(nib,coderev);        Fnum := Fnum SHL 4;        FNum := Fnum OR coderev;        end; { end of NByte2x nibbles}      RADSSetup := FNum;      END;    end;  { end read setup code }  K :=0;  BusyBit := PORT[rdaddr] AND $80;  While (BusyBit <> $80) AND (K <= 200000) do    begin    BusyBit := PORT[rdaddr] AND $80;    inc(K);    if (K mod 80) = 0 then delay(1);    if K = 200000 then SURdError := True;    end;  PORT[wraddr] := $E0;  delay(1);  PORT[strbaddr] := 1;  delay(0);  PORT[strbaddr] := 0;  delay(1);end;procedure ReadData(Nt : longint; ConvertTime : Real;                      var OldReadTime : Real;                      var DRdError : Boolean);{ Needs 32 bit CMR code from main program.This procedure checks data valid untill ready,read the word 4 bits at a time, MSB first,reassemble it, determines data format,(unipolar2's completement MSByte), returns a final 24bitnumber (Fnum) in the proper format}var  FNum          : Longint;  readbkloop    : Longint;  J             : Longint;  BusyBit       : Byte;    { data ready bit }  nib           : Byte;    { nibble from MC51 }  Hour          : Word;  Minute        : Word;  Second        : Word;  Sec100        : Word;  RdError       : Boolean;  iRd           : Word;  K             : Word;  normdata      : Real;  FScale        : Real;  NewReadTime   : Real;  DelTime       : Real;  DataTime      : Real;  coderev       : Byte;  Dbyte2        : Byte;  Dbyte1        : Byte;  Dbyte0        : Byte;begin  DataTime := (Nt+100) * ConvertTime;  DelTime := 0;  while DelTime < DataTime do    begin    GetTime(Hour, Minute, Second, Sec100);    NewReadTime := 3600*Hour + 60*Minute + Second + Sec100/100;    DelTime := NewReadTime - OldReadTime;    if KeyPressed AND (ReadKey = chr(27)) then DelTime := DataTime;    end;  FScale := 16777216;  {Send MCODE=MCretrive to evaluation board}  DRdError :=  False;  K := 0;  Busybit := PORT[rdaddr] AND $80;  while (Busybit <> $80) AND (K <= 200000)  do    begin    Busybit := PORT[rdaddr] AND $80;    inc(K);    if (K mod 80) = 0 then delay(1);    if K = 200000 then DRdError := True;    end;  PORT[wraddr] := $20;  delay(1);  PORT[strbaddr] := 1;  delay(0);  PORT[strbaddr] := 0;  delay(1);  {Wait for evaluation board data valid}  K := 0;  BusyBit := PORT[rdaddr] AND $80;  While (BusyBit <> $80) AND (K <= 200000) do    begin    BusyBit := PORT[rdaddr] AND $80;    inc(K);    if (K mod 80) = 0 then delay(1);    if K = 200000 then DRdError := True;    end;  if DRdError = False then    begin    for J := Nt-1 downto 0 do      begin      Fnum := 0;      for iRd := 1 to NByte2x do        begin        PORT[strbaddr] := $02;        delay(0);        PORT[strbaddr] := 0;        delay(1);        nib := (PORT[rdaddr] AND $78) SHL 1;        revbit(nib,coderev);        Fnum := Fnum SHL 4;        FNum := Fnum OR coderev;        end;{ In the case of MSByte first, MSB first and 2's complement }      if (Fnum AND $800000) > 1 then        Fnum := Fnum OR $FF000000      else        Fnum := Fnum AND $7FFFFF;      normdata :=  Fnum / FScale;      writeln('The Data [',J,'] = ',10*normdata:8:7, '  Volts');      end;    end;  K :=0;  BusyBit := PORT[rdaddr] AND $80;  While (BusyBit <> $80) AND (K <= 200000) do    begin    BusyBit := PORT[rdaddr] AND $80;    inc(K);    if (K mod 80) = 0 then delay(1);    if K = 200000 then DRdError := True;    end;  PORT[wraddr] := $E0;  delay(1);  PORT[strbaddr] := 1;  delay(0);  PORT[strbaddr] := 0;  delay(1);  GetTime(Hour, Minute, Second, Sec100);  OldReadTime := 3600*Hour + 60*Minute + Second + Sec100/100;end;procedure PCPort;begin  {Get LPT1 or LPT2 Address from BIOS Memory}  {LPT1}  pPrintPort := Ptr($40,$08);  {LPT2}  {pPrintPort := Ptr($40,$0A);}  wraddr := pPrintPort^;  rdaddr := wraddr + 1;  strbaddr := wraddr + 2;end;{***********************}{***  Main Program   ***}{***********************}begin{ ADS1210 Configuration }  {INSR = 01100100}  INSRegCode := $64;  {CMR = 01000010_00100000_00000001_01000110}  CMRegCode := $40200146;  {OCR = 00000000_00000000_00000000}  OCRegCode := $000000;  {FCR = 10100011_01110101_10010100}  FCRegCode := $A37594;{Address Definiton}  XAddr_DOR2 := $00;  XAddr_DOR1 := $01;  XAddr_DOR0 := $02;  XAddr_INSR := $03;  XAddr_CMR3 := $04;  XAddr_CMR2 := $05;  XAddr_CMR1 := $06;  XAddr_CMR0 := $07;  XAddr_OCR2 := $08;  XAddr_OCR1 := $09;  XAddr_OCR0 := $0A;  XAddr_FCR2 := $0C;  XAddr_FCR1 := $0D;  XAddr_FCR0 := $0E;  XAddr_ADS  := $0B;{ADSID = $00 for ADS1210/11 and $01 for ADS1212/13 }  ADSID      := $00;  Nbyte2x    := 6;  ReadBack   := False;{Run procedures}  writeln('AP10PC Program (SPISC)');  PCPort;  delay(1000);  Renew;  delay(1000);  Retrieve;end.