FUNCTION "FifoOut" : Void
TITLE = Fifo-Modul
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : IBAE
FAMILY : FIFO
NAME : FifoIn
VERSION : 0.1
//COPYRIGHT by Ingenieurbüro A.Emmert
//Ortsstr.33, D-869925 Fuchstal (Germany)
//Tel.: 0049(0)8243-1254
//Version: ILS2100 / 06.11.2009
//
//Datenblock in Fifo lesen, aus Fifo austragen
//SSDB:    FIFO-DB
//SSDW:    FIFO-1.DW
//PARA:    Aufrufparameter XXYZ:
//     XX: 00 = nächsten Eintrag lesen
//         01,02...,224 = Eintrag 1,2,...,224 lesen
//         E1 = nächsten Eintrag lesen + austragen!
//         E2 = Nur Zusatzdaten lesen
//           YZ: 00 = Keine Zusatzdaten zum lesen
//      Y:  1 - 4 = Beginn, ab welchem Zusatzwort lesen
//      Z:  1 - 4 = Ende, bis zu welchem Zusatzwort lesen
//OUTDATEN: Pointer, wohin ausgelesene Daten übergeben werden (P#DB1.DBX0.0, 
//                                                             P#M220.0) 
//RE_VAL:  Rückmeldungen:
//   Bit0: Kein Fifobereich / falscher Kopfinhalt / Endekennung
//   Bit1: SFC20-Aufruf mit Fehler
//   Bit2: Fifo ist leer
//   Bit3: Falscher Parameter bei Aufruf
//   Bit4: Frei
//   Bit5: Bringzeiger ist ausserhalb
//   Bit6: Holzeiger ist ausserhalb
//   Bit7: Versatz Bring-/Holzeiger
//
   VAR_INPUT 
      SSDB : Int;   // Schnittstellen-DB
      SSDW : Int;   // Schnittstellen-1.DW
      PARA : Word;   // Aufrufparameter (Auftrag / Anzahl Zusatzdaten)
   END_VAR

   VAR_OUTPUT 
      OUTDATEN : Pointer;   // OutDaten-Schnittstelle
      RE_VAL : Byte;   // Rückmeldung
   END_VAR

   VAR_TEMP 
      Quelle : Any;   // Zeiger, wo Rein-Daten sind
      Ziel : Any;   // Zeiger, FIFO-Stelle
      Kopf : Byte;   // Fifo-Kennung (FF)
      Datensatzlaenge : Byte;   // Datensatzlänge in Word (1 - 128)
      FifoLaenge : Int;   // Länge des Fifo (maximale Anzahl der Datensätze)
      Bringzeiger : Int;   // Zeiger, wohin nächster Eintrag gespeichert wird
      Holzeiger : Int;   // Zeiger, woher nächste Daten geholt werden
      Anzahl : Int;   // Anzahl der Datensätze (eingetragene)
      Status : Word;   // Status des Fifo
      Err : Byte;   // Fehlerbits
      Para1 : Byte;   // 1.Aufrufparameter
      Para2 : Byte;   // 2.Aufrufparameter
      Para21 : Byte;   // 2.Aufrufparameter 1.Stelle
      Para22 : Byte;   // 2.Aufrufparameter 2.Stelle
      MinHolzeiger : Int;   // Minimum Holzeiger
      MaxHolzeiger : Int;   // Maximum Holzeiger
      DBFifo : Word;   // FIFO-DB
      SFC_RET_VAL : Int;   // Rückmeldung SFC-Aufruf
      SFC_DB_LENGTH : Word;   // Rückmeldung SFC-Aufruf
      Fifo_Ende : Word;   // Ende des Fifo
      Schleife : Word;   // Loopzähler
      Offset : Byte;   // Offset 1. zu lesendes Zusatzwort
      SFC_WRITE_PROT : Bool;   // Rückmeldung SFC-Aufruf
      NixSave : Bool;   // Status nicht speichern
      BieSpeicher : Bool;   // Bie-Bit zwischenspeichern
      Lesezeiger : Int;   // Lesezeiger
      Diff : Int;   // Differenz
   END_VAR


BEGIN
NETWORK
TITLE = Schnittstellen-DB sinnvoll ?
      L #SSDB;
      T #DBFifo;

//      CALL  TEST_DB
//         DB_NUMBER  :=#DBFifo
//         RET_VAL    :=#SFC_RET_VAL
//         DB_LENGTH  :=#SFC_DB_LENGTH
//         WRITE_PROT :=#SFC_WRITE_PROT

      CALL "TEST_DB_TO_ATTR_DB"
      (  DB_Number                   := #DBFifo , 
         RetVal                      := #SFC_RET_VAL , 
         DB_Length                   := #SFC_DB_LENGTH , 
         Write_Prot                  := #SFC_WRITE_PROT
      );

      L #SFC_RET_VAL;
      L 2#0000_0000_0000_0000;
      <>I;
      O #SFC_WRITE_PROT;
      = #NixSave;//Status nicht speichern
      SPB Err0;//kein Fifobereich

NETWORK
TITLE = Fifokopfdaten holen
//Quelle-Pointer erzeugen:
      L 16#1004;//Kennung 10 + Word=04
      T %LW0;//Any-Kennung, Datentyp
      L 16#0006;//6 Dw´s holen
      T %LW2;//Wiederholungen
      L #SSDB;
      T %LW4;//DB_Nummer
      L #SSDW;//Adresse
      SLD 3;
      L 16#8400_0000;//Kennung: Daten
      OD;
      T %LD6;//Kennung, Adresse

      CALL BLKMOV//1.-6.DW FIFO holen
      {blk_type := 'Variant'}
      (  SRCBLK                      := #Quelle , 
         RET_VAL                     := #SFC_RET_VAL , 
         DSTBLK                      := P#L20.0 WORD 6
      );

      L #Status;
      L 2#0000_0000_1110_0000;
      UW;
      T #Err;
      SPP Err;//Kapitalfehler vorhanden

      L #SFC_RET_VAL;
      L 2#0000_0000_0000_0000;
      <>I;
      SPB Err1;

NETWORK
TITLE = Zeigerüberprüfung
      L #Kopf;//Fifo-Kopf
      L 16#FF;//= Fifokennung ?
      <>I;//Nein !
      = #NixSave;//Status nicht speichern
      SPB Err0;//kein Fifobereich

      L 1;
      L #Datensatzlaenge;//Datenblocklänge
      >I;
      SPB Err0;//kein Fifobereich

      L 128;
      >I;
      SPB Err0;//kein Fifobereich

      L 1;
      L #FifoLaenge;//Max.Anzahl von Datenblöcken
      >I;
      SPB Err0;//kein Fifobereich

      L #SSDW;
      + 40;//Speichern ab 20.DW
      T #MinHolzeiger;//Minimum Holzeiger

      L #FifoLaenge;//Länge FIFO (in Word)
      + -1;
      L #Datensatzlaenge;//Datenblocklänge
      *I;
      L 2;//DB byteorientiert
      *I;
      + 40;//Speichern ab 20.DW
      L #SSDW;
      +I;
      T #MaxHolzeiger;//Maximum Holzeiger

      L #Datensatzlaenge;//Datenblocklänge
      L 2;//DB byteorientiert
      *I;
      L #MaxHolzeiger;//Maximum Holzeiger
      +I;//Zeiger Endekennung
      T #Fifo_Ende;
      SLW 3;//Pointer erzeugen
      LAR1;

      AUF DB[ #DBFifo];

      L #Fifo_Ende;
      L #SFC_DB_LENGTH;
      >I;//Fifo-DB ist zu kurz!
      SPB Err0;//kein Fifo-Bereich

      L DBW[ AR1, P#0.0];
      L 16#FFEE;//Fifo-Endekennung ?
      <>I;//Nein !
      SPB Err0;//kein Fifobereich

      L #MinHolzeiger;//Minimum Holzeiger
      L #Holzeiger;//Holzeiger
      <=I;//Ok ?
      SPB W300;//Ja!

      L 0;//Grundstellung ?
      <>I;//Nein !
      SPB Err6;//Holzeiger ist ausserhalb

      L #Bringzeiger;//Bringzeiger Grundstellung ?
      <>I;//Nein !
      SPB Err6;//Holzeiger ist ausserhalb

      L #Anzahl;//Anzahl Datensätze
      L 0;//Grundstellung ?
      <>I;//Nein !
      SPB Err6;//Holzeiger ist ausserhalb

      L #MinHolzeiger;//Minimum Holzeiger
      T #Bringzeiger;//Bringzeiger
      T #Holzeiger;//Holzeiger

      SPA Zus;//Zusatzdaten lesen ?

W300:      L #MaxHolzeiger;//Maximum Holzeiger
      <=I;//Ok ?
      SPB W301;//Ja!
      SPA Err6;//Holzeiger ist ausserhalb


W301:      L #Bringzeiger;//Bringzeiger
      L #Holzeiger;//Holzeiger
      ==I;//Identisch !
      U(;
      L #FifoLaenge;
      L #Anzahl;//Anzahl der gespeicherten Datensätze
      <>I;//Fifo noch nicht voll !
      );
      U(;
      L 0;
      <>I;//Datensätze aber noch vorhanden !
      );
      SPB Err7;//Versatz Bring-/Holzeiger

      L #Bringzeiger;//Bringzeiger
      L #Holzeiger;//Holzeiger
      <>I;//Ungleich !
      U(;
      L #FifoLaenge;
      L #Anzahl;//Anzahl der gespeicherten Datensätze
      ==I;//Aber Fifo ist voll !
      O(;
      L 0;
      ==I;//Aber keine Datensätze vorhanden !
      );
      );
      SPB Err7;//Versatz Bring-/Holzeiger

NETWORK
TITLE = Zusatzdaten lesen ?
Zus:      L #PARA;
      T %LW33;//Aufrufparameter zwischenspeichern

      L 16#E2;//Nur Zusatzdaten lesen ?
      L #Para1;//1.Aufrufparameter
      ==I;//Ja !
      U(;
      L #Para2;//2.Aufrufparameter
      L 16#00;//=0 ?
      ==I;//Ja !
      );
      SPB Err3;//Falscher Aufrufparameter

      L 16#00;//=0 ?
      L #Para2;//2.Aufrufparameter
      ==I;//Ja !
      SPB Nw05;//Keine Zusatzdaten lesen

      L 16#00F0;
      UW;
      SRW 4;
      T #Para21;//1.Stelle isolieren

      L #Para2;//2.Aufrufparameter
      L 16#000F;
      UW;
      T #Para22;//2.Stelle isolieren

      L #Para21;
      L #Para22;
      >I;//1.Stelle > 2.Stelle !
      SPB Err3;//Falscher Aufrufparameter

      L 16#04;
      >I;//2.Stelle > 4 !
      SPB Err3;//Falscher Aufrufparameter

      L #Para21;
      L 16#00;
      ==I;//1.Stelle = 0 !
      SPB Err3;//Falscher Aufrufparameter

//Quelle-Pointer erzeugen:
      L 16#1004;//Kennung 10 + Word=04
      T %LW0;//Any-Kennung, Datentyp
      T %LW10;//Any-Kennung, Datentyp
      L #Para22;//bis
      L #Para21;//von    
      -I;
      + 1;
      T %LW2;//Wiederholungen
      T %LW12;//Wiederholungen

      L #Para21;//Beginn ab X.Zusatzwort
      + -1;
      L 2;//byteorientiert
      *I;
      T #Offset;//Offset 1. zu speicherndes Zusatzwort

      L #SSDB;
      T %LW4;//DB_Nummer
      L #SSDW;
      + 12;//ab 6.Dw lesen
      L #Offset;//falls nicht ab 1.Zusatzwort
      +I;
      SLD 3;
      L 16#8400_0000;//Kennung: Daten
      OD;
      T %LD6;//Kennung, Adresse

//Ziel-Pointer erzeugen:
//Kennung + Datenbytes s.o.

      L 0;
      T %LW14;//DB_Nummer

      L 16#00F0;//Adresse  (MW240)
      L #Offset;//falls nicht ab 1.Zusatzwort
      +I;
      SLD 3;
      L 16#8300_0000;//Kennung: Merker
      OD;
      T %LD16;//Kennung, Adresse

      CALL BLKMOV//Zusatz-Daten speichern
      {blk_type := 'Variant'}
      (  SRCBLK                      := #Quelle , 
         RET_VAL                     := #SFC_RET_VAL , 
         DSTBLK                      := #Ziel
      );

      L #SFC_RET_VAL;
      L 2#0000_0000_0000_0000;
      <>I;
      SPB Err1;

NETWORK
TITLE = Fifodaten lesen
Nw05:      L #Para1;//1.Aufrufparameter
      L 16#E2;//Nur Zusatzdaten lesen ?
      ==I;//Ja !
      SPB Ende;//Fertig !

      L #Anzahl;//Anzahl der gespeicherten Datensätze
      L 0;
      ==I;//Keine Datensätze vorhanden !
      SPB Err2;//Fifo ist leer

//Quelle-Pointer erzeugen:

      L 16#1004;//Kennung 10 + Word=04
      T %LW0;
      T %LW10;//Any-Kennung, Datentyp
      L #Datensatzlaenge;//Datenbytes speichern
      T %LW2;
      T %LW12;//Wiederholungen

      L #SSDB;
      T %LW4;//DB_Nummer

      L #Holzeiger;//Adresse  (erstmal !, falls Para 2=0)
      T #Lesezeiger;//Lesezeiger
      L #Para1;//1.Aufrufparameter
      L 16#00;//=0 ?
      ==I;
      O(;
      TAK;
      L 16#E1;//Datensatz löschen ?
      ==I;//Ja !
      );
      SPB w050;

      TAK;//X-te Stelle lesen
      + -1;//-1, da 1.ohne Offeset
      L #Datensatzlaenge;//Datenblocklänge
      *I;
      L 2;//DB byteorientiert
      *I;
      L #Holzeiger;//Adresse
      +I;
      T #Lesezeiger;//Lesezeiger
      L #MaxHolzeiger;//Maximum Holzeiger
      <=I;//Ist nicht über Maximum !
      SPB w050;

      L #FifoLaenge;//Länge FIFO (in Word)
      L #Datensatzlaenge;//Datenblocklänge
      *I;
      L 2;//DB byteorientiert
      *I;
      T #Diff;

      L #Lesezeiger;//Differenz subtrahieren:
      L #Diff;
      -I;
      T #Lesezeiger;//Lesezeiger

w050:      L #Lesezeiger;//Lesezeiger
      SLD 3;
      L 16#8400_0000;//Kennung: Daten
      OD;
      T %LD6;//Kennung, Adresse

//Ziel-Pointer erzeugen:
//Kennung + Datenbytes s.o.

//DATEN-Pointer übernehmen:
      L P##OUTDATEN;
      LAR1;

      L W[ AR1, P#0.0];
      T %LW14;//DB_Nummer
      L D[ AR1, P#2.0];
      T %LD16;//Kennung, Adresse

      CALL BLKMOV//FIFO-Daten speichern
      {blk_type := 'Variant'}
      (  SRCBLK                      := #Quelle , 
         RET_VAL                     := #SFC_RET_VAL , 
         DSTBLK                      := #Ziel
      );

      L #SFC_RET_VAL;
      L 2#0000_0000_0000_0000;
      <>I;
      SPB Err1;

NETWORK
TITLE = Daten aus Fifo austragen ?
      L 16#E1;//Daten löschen ?
      L #Para1;//1.Aufrufparameter
      <>I;//Nein !
      SPB Ende;//Fertig !

      L #Holzeiger;//Holzeiger
      SLW 3;//Pointer erzeugen
      LAR1;

      AUF DB[ #DBFifo];

      L #Datensatzlaenge;
L600:      T #Schleife;

      L 0;
      T DBW[ AR1, P#0.0];

      +AR1 P#2.0;

      L #Schleife;
      LOOP L600;

NETWORK
TITLE = Holzeiger, Anzahl erniedrigen
      L #Datensatzlaenge;//Datenblocklänge
      L 2;//1 word = 2 bytes
      *I;
      L #Holzeiger;//Holzeiger
      +I;
      T #Holzeiger;//Holzeiger
      L #MaxHolzeiger;//Maximum Holzeiger
      <=I;//Erreicht ?
      SPB W700;//Nein !

      L #MinHolzeiger;//Minimum Holzeiger
      T #Holzeiger;//Holzeiger

W700:      L #Anzahl;//Anzahl der gespeicherten Datensätze
      + -1;
      T #Anzahl;//Anzahl der gespeicherten Datensätze

NETWORK
TITLE = Versatz Bring-/Holzeiger
      L #Bringzeiger;//Bringzeiger
      L #Holzeiger;//Holzeiger
      ==I;//Identisch !
      U(;
      L #Anzahl;//Anzahl der gespeicherten Datensätze
      L 0;
      <>I;//Datensätze aber noch vorhanden !
      );
      SPB Err7;//Versatz Bring-/Holzeiger

      L #Bringzeiger;//Bringzeiger
      L #Holzeiger;//Holzeiger
      <>I;//Ungleich !
      U(;
      L #Anzahl;//Anzahl der gespeicherten Datensätze
      L 0;
      ==I;//Aber keine Datensätze vorhanden !
      );
      SPB Err7;//Versatz Bring-/Holzeiger

NETWORK
TITLE = Fehlerausgabe / RET_VAL
Ende:      SET;//VKE = 1 ohne Fehler !!!
      SPA Ok;
Err0:      L 2#0000_0000_0000_0001;//Kein Fifobereich
      T #Err;
      SPA Err;
Err1:      S %L32.1;//SFC20-Aufruf mit Fehler
      SPA Err;
Err2:      S %L32.2;//Fifo ist leer
      SPA Err;
Err3:      S %L32.3;//Falscher Parameter
      SPA Err;
Err6:      S %L32.6;//Holzeiger außerhalb
      SPA Err;
Err7:      S %L32.7;//Versatz Bring-/Holzeiger

Err:      CLR;//VKE = 0 bei Fehler !!!
Ok:      L #Err;
      T #RE_VAL;
      L #Status;
      OW;
      T #Status;

      SAVE;//VKE in BIE-Bit speichern  
      U BIE;
      = #BieSpeicher;
NETWORK
TITLE = Fifokopfdaten speichern
      U %L32.0;//Falscher Parameter
      U #NixSave;//Status nicht speichern
      BEB;

//Ziel-Pointer erzeugen:

      L 16#1004;//Kennung 10 + Word=04
      T %LW10;//Any-Kennung, Datentyp
      L 16#0004;//4Dw´s speichern
      T %LW12;//Wiederholungen
      L #SSDB;
      T %LW14;//DB_Nummer
      L #SSDW;//Adresse
      L 4;
      +I;
      SLD 3;
      L 16#8400_0000;//Kennung: Daten
      OD;
      T %LD16;//Kennung, Adresse

      CALL BLKMOV//Ab Bringzeiger sichern!
      {blk_type := 'Variant'}
      (  SRCBLK                      := P#L24.0 WORD 4 , 
         RET_VAL                     := #SFC_RET_VAL , 
         DSTBLK                      := #Ziel
      );

      U #BieSpeicher;
      SAVE;//VKE in BIE-Bit speichern  

END_FUNCTION

