[Back to HARDWARE SWAG index] [Back to Main SWAG index] [Original]

    {
                  Unit       :Eeprom
    	      File       :EEPROM.PAS
                  Author     :Ivan Beltrame (ivan.beltrame@nline.it)
                  Date       :5 August 1997
                  Rev.       :1.00b

                  Note       :This unit provide to read and write in 93xx EEPROM.
                              93xx chip are present in many circuit board to
                              storage of a password,to retain some data in non
    			  volatile memory,or to limit the 'life' of a device.
                              It is very easy to use it but this version has
                              a little 'bug' : *timing !*
                              Since I'm a TP6 beginner I'm not able to implement
                              a *compact* and *serious* "delay" routine that run
    			  over microsecond or nanosecond, then I have used
    			  "FastWait" unit by Southern Software from the
    			  SWAG archive (not included in this source).
                              Use of this unit it's free, but comments on my
                              programming mode (self-made) will be apreciated.

                  Important  :I decline any responsibilities or liabilities
                              resulting from the use of these informations
                              (source and schematics).

    	           ------------------------------------------------------

                              Pin connections of the parallel port vs chip:

                          LPTx                    chip
                           v                       v

                                              ____________
                                      2 K    !   o        !
                         16(C2)   ---\/\/\---! 1(CS)    8 !------> +5 Volt
                                      2 K    !            !
                         2 (D0)   ---\/\/\---! 2(CK)    7 !--x
                                      2 K    !            !
                         1 (C0)   ---\/\/\---! 3(DI)    6 !--x
                                    100 ohm  !            !
                         11(S7)   ---\/\/\---! 4(DO)    5 !---*---> GND
                                             !____________!   I
                                                              I
                         18(GND)  ____________________________I

                                                 9306
                                                 9346

    }

    Unit Eeprom;

    interface

    var
      PData      :word;                            { may be $378 or $278 or $3BC }

    procedure LptInit;                { initialize LPTx wires and port registers }
    procedure Eral;                            { reset all registers in the chip }
    procedure Wral(EEfill :word);             { write all reg. with EEfill value }
    procedure EraseLoc(Erase_Loc :byte);                      { reset a register }
    procedure EEwrite(WrLoc :byte; WrValue :word);         { write in a register }
    function EEvalue(Loc :byte) :word;               { return a register's value }

    { Notice: Eral procedure sets all registers at $FFFF;  EraseLoc sets
              selected location to $FFFF. }

    implementation

    uses
      crt, FastWait; { also available in SWAG  -- TIMING.SWG}

    var
      Weight     :word;
      s          :byte;
      PStatus    :word;
      PControl   :word;

    procedure CK;

    { Generate a clock pulse in the CK wire }
    { Produce un impulso di clock sul filo CK }

    begin
      Wait(2);                                { ritardo dopo il dato (2 mS) }
      port[PData] := port[PData] or 1;        { CK = 1 }
      Wait(4);                                { tempo di CK alto (4 mS) }
      port[PData] := port[PData] and 254;     { CK = 0 }
      Wait(6);                                { tempo di CK basso (6 mS) }
    end;

    procedure CSon;

    { Abilita il chip (Chip Select on) *e lo lascia abilitato* }
    { Enable the chip (Chip Select on) *and it remain still enabled* }

    begin
      Wait(4);                                { ritardo dal precedente CSon }
      port[PControl] := port[PControl] or 4;  { CS = 1 }
      CK;                                     { un CK a vuoto (necessario) }
    end;

    procedure CSoff;

    { Disabilita il chip (Chip Select off) *e lo lascia disabilitato* }
    { Disable the chip (Chip Select off) *and it remain still disabled* }

    begin
    	port[PControl] := port[PControl] and 251;  { CS = 0 }
    end;

    procedure DI1;

    { Attiva il filo DI (Data Input) del chip }
    { Brought DI wire (Data Input) high }

    begin
      port[PControl] := port[PControl] and 30;   { DI = 1 }
    end;

    procedure DI0;

    { Disattiva il filo DI (Data Input) del chip }
    { Brought DI wire (Data Input) low }

    begin
      port[PControl] := port[PControl] or 1;     { DI = 0 }
    end;

    procedure LptInit;

    begin
      PStatus := PData + 1;
      PControl := PData + 2;
      CSoff;                         { evita confusioni }
      DI0;                           { evita confusioni }
    end;

    procedure EEcmd(EEcode :word;EEloc :byte);

    { Invia il codice operativo al chip }
    { Send operating code to the chip }

    begin
      CSon;
      EEcode := EEcode + EEloc;     { Codice operativo = Operazione + Locazione }
      for s:= 8 downto 0 do
      begin                         { invia stringa di bit seriali sul filo DI }
        Weight := 1 shl(s);
        if EEcode < Weight then
        begin
          DI0; CK;
        end
        else
        begin
          EEcode := EEcode - Weight;
          DI1; CK;
        end;
      end;
    end;

    procedure Ewen;

    { Ordine di abilitazione alla scrittura/cancellazione al chip }
    { Enable command for writing/erasing operations to the chip }

    const
      EwenCode     = 304;

    begin
      EEcmd(EwenCode,0);            { il campo EELoc deve essere = 0 }
      DI0;                          { ripristina DI = 0 (evita confusioni) }
      CSoff;                        { disabilita il chip dopo il comando }
    end;

    procedure Ewds;

    { Ordine di disabilitazione alla scrittura/cancellazione al chip }
    { Disable command for writing/erasing operations to the chip }

    const
      EwdsCode     = 256;

    begin
      EEcmd(EwdsCode,0);            { il campo EELoc deve essere = 0 }
      CSoff;                        { disabilita il chip dopo il comando }
    end;

    procedure Eral;

    { Ordine di cancellazione totale al chip. Tutte le loc diventeranno $FFFF }
    { Erase all command to the chip. All locations become $FFFF }

    const
      EralCode     = 288;

    begin

      Ewen;                         { abilita il chip alla cancellazione totale }

      EEcmd(EralCode,0);            { il campo EELoc deve essere = 0 }
      CSoff;                        { disabilita il chip dopo il comando }

      Ewds;                         { disab. il chip alla cancellazione totale }

    end;

    procedure Wral(EEfill :word);

    { Ordine di riempimento delle loc del chip con un valore 'EEfill' }
    { Fill all locations with 'EEfill' value }

    const
      WralCode     = 272;

    begin

      Eral;                         { "ERAL" necessario per affidabilita' }

      Ewen;                         { abilita il chip alla scrittura }

      EEcmd(WralCode,0);            { comando "WRAL" }
      for s:= 15 downto 0 do
      begin                         { invia stringa di bit seriali }
        Weight := 1 shl(s);         { per specificare il dato di }
        if EEfill < Weight then     { riempimento }
        begin
          DI0; CK;
        end
        else
        begin
          EEfill := EEfill - Weight;
          DI1; CK;
        end;
      end;
      DI0;                          { ripristina DI = 0 (evita confusioni) }
      CSoff;                        { Disabilita il chip }

      Ewds;                         { disab. il chip alla scrittura }

    end;

    procedure EraseLoc(Erase_Loc :byte);

    { Ordine di resettare una locazione; il suo valore diventera' $FFFF }
    { Reset command for a single location; it become $FFFF }

    const
      EraseCode = 448;

    begin

      Ewen;                         { abilita il chip alla cancellazione }

      EEcmd(EraseCode,Erase_Loc);   { il campo Erase_Loc deve avere il }
      DI0;                          { ripristina DI = 0 (evita confusioni) }
      CSoff;                        { numero della locazione da resettare }

      Ewds;                         { disab. il chip alla cancellazione  }

    end;

    procedure EEwrite(WrLoc :byte; WrValue :word);

    { Ordine di scrivere un dato 'WrValue' alla loc 'WrLoc' }
    { Writing command; it will write a 'WrValue' in a 'WrLoc' location }

    const
      WrCode  = 320;

    begin

      Ewen;                            { abilita il chip alla scrittura }

      EEcmd(WrCode,WrLoc);             { comando di scrittura alla loc WrLoc }
      for s:= 15 downto 0 do
      begin                            { invia stringa di bit seriali sul DI }
        Weight := 1 shl(s);
        if WrValue < Weight then
        begin
          DI0; CK;
        end
        else
        begin
          WrValue := WrValue - Weight;
          DI1; CK;
        end;
      end;
      DI0;                             { ripristina DI = 0 (evita confusioni) }
      CSoff;                           { disabilita il chip }

      Ewds;                            { disabilita il chip alla scrittura }

    end;

    function EEvalue(Loc :byte) :word;

    { Ritorna il valore letto nella 'Loc' }
    { It return a Loc's value }

    const
      ReadCode      = 384;
    var
      Value         :byte;
      EEval         :word;

    begin
      EEvalue := 0;
      EEval   := 0;
      EEcmd(ReadCode,Loc);             { comando di lettura alla 'Loc' }
      for s := 0 to 15 do
      begin
        CK;                            { invia impulso di clock }
        wait(5);
        Value := port[PStatus];        { legge sul filo DO il livello logico }

        if Value < 128 then EEval :=  EEval + (1 shl(15 - s));

        { poiche' quando il filo "S7" della porta e' a "1" il peso 7 del byte }
        { di stato e' a "0" potremmo dire di avere un "1" quando Value < 128. }
        { Se ad ogni ciclo incrementiamo o decrementiamo i pesi di EEval a }
        { seconda del valore di DO, ci ritroveremo col dato della locazione. }

      end;
      DI0;                             { ripristina DI = 0 (evita confusioni) }
      CSoff;                           { disabilita il chip }
      EEvalue := EEval;
    end;

    End.

    { There are some examples }

    {

    program EEpromTest;

    uses EEprom;

    var
      j  :byte;
      h  :word;

    begin
      PData := $378;                 { You must specify the parallel port in use }
      LptInit;                       { initialize LPTx wires and port regs }
      writeln('Reading test on EEPROM 9306');
      writeln;

      for j := 0 to 15 do            { this "for"cicle put on "h" }
      begin                          { the "j" location           }
        h := EEvalue(j);             { of the EEPROM chip         }
        write (h,' ');               {                            }
      end;

      readln;

      Eral;                          { this procedure sets all regs }
                                     { in the EEPROM chip = 65535   }
      readln;
      h := 100;

      Wral(h);                       { this procedure sets all regs }
                                     { in the EEPROM chip = "h"     }
      readln;
      j := 5;

      EraseLoc(j);                   { this procedure sets the "j"  }
                                     { reg in the EEPROM = 65535    }
      readln;
      j := 10;
      h := 1500;
      EEwrite(j,h);                  { this procedure sets the reg  }
                                     { "j" = "h" in the EEPROM      }
                                     { Notice : in certain cases it }
                                     { is necessary to perform an   }
                                     { EaseLoc(j) before of EEwrite(j,.... }

    end.

[Back to HARDWARE SWAG index] [Back to Main SWAG index] [Original]