Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - FAQ - Zum CC1-Forum - Zum CC-Pro-Forum

Neuer i2c-eeprom-Treiber (beta) Kategorie: I²C-Bus (von Rolf - 4.08.2003 18:24)


Hallo,
wie evtl. einige mitbekommen haben, haben André und ich sehr kontroverse Ansichten zu dem
EEPROM-Treiber wie er hier in der Site angeboten wird und ich konnte meine Ideen nicht einbringen.
Ich habe darauf hin beschlossen, einen alternativen EEPROM-Treiber zu schreiben.
Der Treiber ist vorläufig erst mal nur beta und nicht für eigene Programme geeignet.
Ich hab mir auch noch keine Gedanken gemacht, in wie weit er universell und mit anderen Typen als dem
24c512 einsetzbar gemacht werden kann. Ich stelle den Treiber hier nun zur Ansicht bzw. zur Diskusion.
Da er aber noch Macken hat, wird das noch nicht die endgültige Version sein.
Also bitte noch nicht verwenden! Wenn euch Fehler auffallen oder Ihr Vorschläge habt, meldet euch.



/******************************************************************/
/* Treiberbibliothek für eine EEPROM Disk mit 1-4 24C512          */
/* Nur für den privaten Gebrauch, jegliche Haftung ausgeschlossen */
/*                                                                */
/* Autor     : (c) by Rolf Diesing       rolf(at)diesing.net      */
/* Version   : 0.45                                               */
/* Datum     : 4. August 2003                                     */
/* Getestet  : ja, mit BsafEE 1.1 (liegt dem Treiber bei)         */
/* Benötigt  : i2c.c2 ab V1.1 und mem.c2                          */
/******************************************************************/
/* History:                                                       */
/* 22.7.03 1.Fassung, erste Laufzeit Tests, Konzeptprüfung        */
/* 24.7.03 2.Fassung, Optimierungen, nun ca. doppelt so schnell   */
/* 25.7.03 setEEaddr und getEEaddr hinzugefügt, Verify eingebaut  */
/* 29.7.03 CRC-Management, Flags, DoError                         */
/* 1.8.03 Umbau Basis und erweiterte Funktion, Floatfunktionen    */
/* 2.8.03 Cleanup, Docu, Test, Verify überarbeitet                */
/* 4.8.03 komplette Ã?berarbeitung                                 */
/******************************************************************/
/* Funktionsliste des Moduls
//MISC
function init()
function setaddr(long addr,t_EE_addr t) returns long
function oldaddr(long addr,t_EE_addr t) returns long
function cpyaddr(t_EE_addr t1,t_EE_addr t2) returns long
function DoError(t_EE_addr t)
function verifybytearray (t_EE_addr t, byte data[], int len,byte f)
//LESEN
function readbyte (t_EE_addr t,byte f) returns byte
function readint (t_EE_addr t,byte f) returns int
function readlong (t_EE_addr t,byte f) returns long
function readfloat (t_EE_addr t,byte f) returns float
function readbytearray (t_EE_addr t, byte data[], int len,byte f)
function readintarray (t_EE_addr t, int data[], int len,byte f)
function readlongarray (t_EE_addr t, long data[], int len,byte f)
function readfloatarray (t_EE_addr t, float data[], int len,byte f)
function readstr (t_EE_addr t, byte s[],byte f)
//SCHREIBEN
function writebyte (t_EE_addr t, byte data,byte f)
function writeint (t_EE_addr t, int data,byte f)
function writelong (t_EE_addr t, long data,byte f)
function writefloat (t_EE_addr t, float data,byte f)
function writebytearray (t_EE_addr t, byte data[], int len,byte f)
function writeintarray (t_EE_addr t, int data[], int len,byte f)
function writelongarray (t_EE_addr t, long data[], int len,byte f)
function writefloatarray (t_EE_addr t, float data[], int len,byte f)
function writestr (t_EE_addr t, byte s[],byte f)
//DEMO
function readmytype (t_EE_addr t, mytype abc,byte f)
function writemytype (t_EE_addr t, mytype abc,byte f)
*/


/******************************************************************/
/* Kurze Einführung:
Die Funktionsweise des Treibers sollte gelesen und verstanden sein,
wenn man den Treiber oder Teile daraus verwenden möchte.

Der Aufruf von init() vor der ersten Benutzung ist zwingend notwendig.
Es werden dort die Arrays der Memory-Map und des Bitfeldes initialisiert.
Die Funktionen bekommen einen Adresspointer vom Typ t_EE_addr, weitere
Parameter je nach Wertetyp und am Schlu� ein Flag-Byte übergeben.
Arrayfunktionen erhalten zu vorletzt noch eine Längenangabe.
Schreibende Funkionen können eine CRC-Summe aus den Parameterdaten generieren,
die im Addr.Ptr im Typ t_EE_addr.crc eingetragen wird. Es wird die Menge
an verarbeiteten Zeichen in t_EE_addr.used für Adressberechnungen eingetragen.
Lesende Funktionen können eine CRC-Summe aus den gelesenen Daten generieren,
die Summe wird im Addr.Ptr im Typ t_EE_addr.crc eingetragen.
Die CRC-Daten können in das EEPROM geschrieben und mit den später generierten
CRC-Summen verglichen werden. Die CRC-Daten werden ggf. über alle Lese- und
Schreibvorgänge mitgeführt, wenn sie nicht explizit oder mit setEEaddr gelöscht
werden. Es empfielt sich, für schreibende und lesende Funktionen sowie für
CRC-Datenfelder getrennte Addresspointer zu nutzen.
Ã?ber Flags kann das Verhalten der Funktionen gesteuert werden.
Die Konstanten der Bits können binär zu einem Flag addiert werden.
Die Adressen werden automatisch in t_EE_addr.addr incrementiert, so das für
sequentielle Zugriffe kein Aufwand für Adressberechnung erfolgt.
Die Addresierung erfolgt als long und kann derzeit von 0 bis 262143 erfolgen.
Um Speicherlücken auszugleichen, erfolgt der Zugriff über eine Memory-Map die
evtl. angepasst werden muÃ?. Die Bausteinauswahl erfolgt dann automatisch.
Die Funktionen sind durch Capture in der Nähe der i2c-Operationnen gegen
gegenseitiges Stören/�berschreiben auf dem I2C-Bus geschützt. Leider klappt
das Sperren mit i2c.cstart nicht, da anscheinend dann wait nicht mehr
ausgeführt wird. Das führt zu einem Deadlock. Ein Capture für den
jeweiligen Ard.Ptr wie ursprünglich geplant ist mit c2 nicht möglich.
Es werden alle Datentypen unterstützt und ein Beispiel für eigene Typen und
für die Nutzung von CRC ist am Schlu� eingefügt.
*/

/******************************************************************/

const default = 0; //default, Verify aus, CRC aus, 32Bit
//const frei = 1; //LSB not used
const DoV = 2; //1=vergleicht beim schreiben und springt DoError an,0=do nothing
const DoCRC = 4; //1=schaltet CRC schreibend ein,0=do nothing
const CRC16 = 8; //1=16,0=32, wirkt nur wenn DoCRC=1
//const frei = 16; //BIT not used - reserved
//const frei = 32; //BIT not used - reserved
//const frei = 64; //BIT not used
//const frei = 128; //MSB not used

const EEblock=128; //Blocksize EEPROM laut Datenblatt

type t_EE_addr
{
  long addr;
  long crc;
  int used;
}

byte EEmmap[7];//gehört zu init();
byte EEpw[7];//Bitarray für CRC und Bitmustervergleiche

function init()//init Funktiom für Memory Map
// Es sind bis max 256 KB Speicher adressierbar. Das Ã?ndern dieser Funktion
// erlaubt Eingriffe in das Speichermanagement vergleichbar mit einer einfachen
// MMU und soll hardwarebedingte Speicheradressenlücken verhindern helfen.
// Es wären z.Z. technisch nur EEmmap[3] nötig, es soll aber in Zukunft weitere
// Erweiterungen in den Speicher ab 262144 bzw. 0x40000 gelegt werden.
// Aktuell ist die EEmap als Beispiel auf Mirror Betrieb eingestellt.
// Auch die Nutzung anderer EEPROM-Typen ist denkbar, dazu sind aber weitere
// Anpassungen nötig: -> (160 or EEmmap[(t.addr and 262143) shr 16])
{
byte i;        //   Normaler Betrieb 256KB         Betrieb mit PCF-Uhr 192KB
 EEmmap[0]=0; //160 für 24c512 000=A3-A0           EEmmap[0]=0; //160
 EEmmap[1]=2; //162 für 24c512 001=A3-A0           EEmmap[1]=4; //164
 EEmmap[2]=4; //164 für 24c512 010=A3-A0           EEmmap[2]=6; //166
 EEmmap[3]=6; //166 für 24c512 011=A3-A0           EEmmap[3]=0; //166
 EEmmap[4]=0; //160 | z.Z. noch unbenutzt, Mirror Bank 0
 EEmmap[5]=2; //162 | z.Z. noch unbenutzt, Mirror Bank 1
 EEmmap[6]=4; //164 | z.Z. noch unbenutzt, Mirror Bank 2
 EEmmap[7]=4; //164 | z.Z. noch unbenutzt, Mirror Bank 2
 for i = 0 ... 7
    EEpw[i] = 2 ^ i;
}

/*************************************/
/* Setzt Startwerte für Addr.Ptr     */
/*************************************/
function setaddr(long addr,t_EE_addr t) returns long
{
t.addr=addr;
t.used=0;
t.crc=0;
return addr;
}

/*************************************/
/* Setzt Addr neu, gibt alte zurück  */
/*************************************/
function oldaddr(long addr,t_EE_addr t) returns long
{
long data;
data=t.addr;
t.addr=addr;
return data;
}

/*************************************/
/* kopiert ganzen Addr.Ptr von 1 zu 2*/
/*************************************/
function cpyaddr(t_EE_addr t1,t_EE_addr t2) returns long
{
t2.addr=t1.addr;
t2.used=t1.used;
t2.crc=t1.crc;
return t1.addr;
}

/*************************************/
/* Wird im Fehlerfall angesprungen   */
/*************************************/
function DoError(t_EE_addr t, byte f)
{
 //Default für verify Fehler, EEPROM defekt.
 quit 63;
 //ggf. an eigene Anforderungen anpassen.
 //z.b. Ausgabe des Fehlers auf LCD, Alarmton, SMS,
 //umschalten auf Reservespeicherbank (EEmmap) usw.
}

/*************************************/
/* Byte-Array verifizieren           */
/*************************************/
function verifybytearray (t_EE_addr t, byte data[], int len,byte f)
{
int i,fault; //counter für Array
fault=-1;
  if len > 0 // es muÃ? wegen i2c.readlast min. 1 Byte gelesen werden.
  {
   capture i2c.flag; //verifybytearray darf niemals mehrfach ausgeführt werden
   wait i2c.ready(); //wartet auf Busfreigabe und auf EEPROM aus Memorymap
   t.addr=t.addr-len; //Addresskorrektur DoV
   wait i2c.start(160 or EEmmap[(t.addr and 262143) shr 16]);
   i2c.write(t.addr shr 8); //schreibt Adresse im selektierten EEPROM
   i2c.write(t.addr);
   i2c.start(161 or EEmmap[(t.addr and 262143) shr 16]); //setzt lesemodus
   for i=0 ... len-2
     if data[i] != i2c.read()//Vergleichsvorgang des Array data[]
     {  // Abbruch des Vergleichsvorgangs, EEPROM hat falsche Daten
        fault=0;
        len=i;
        break;
     }
   if data[len-1] != i2c.readlast() fault=0;//letztes Byte
   t.used=len; //Längenanpassung
   t.addr=t.addr+len; //Adressanpassung
   i2c.stop(); //Vorgang beendet, Bus ist frei
   release; //verifybytearray ist fertig,
   if fault DoError(t,f);//Vorgang beendet -> Fehlerfall im EEPROM auf t.addr
  }
}

/*************************************/
/* Byte-Array lesen                  */
/*************************************/
function readbytearray (t_EE_addr t, byte data[], int len,byte f)
{
int i,j; //counter für Array
  if len > 0 // es muÃ? wegen i2c.readlast min. 1 Byte gelesen werden.
  {
   capture i2c.flag; //readbytearray darf niemals mehrfach ausgeführt werden
   wait i2c.ready(); //wartet auf Busfreigabe und auf EEPROM aus Memorymap
   wait i2c.start(160 or EEmmap[(t.addr and 262143) shr 16]);
   i2c.write(t.addr shr 8); //schreibt Adresse im selektierten EEPROM
   i2c.write(t.addr);
   i2c.start(161 or EEmmap[(t.addr and 262143) shr 16]); //setzt lesemodus
   for i=0 ... len-2 data[i] = i2c.read(); //Lesevorgang des Array data[]
   data[len-1] = i2c.readlast(); //letztes Byte
   if f and EEpw[DoCRC] == EEpw[DoCRC] //ggf. CRC berechnen
    {
     for i = 0 ... len-1
      {
        for j = 7 ... 0 step -1 //msb zuerst... in asm wäre das schöner
        {
          if ((t.crc and 32768)==32768) xor ((data[i] and EEpw[j])==EEpw[j])
           if f and EEpw[CRC16]==EEpw[CRC16] t.crc=((t.crc and 32767) shl 1) xor 0x1021;
           else t.crc=((t.crc and 32767) shl 1) xor 0x8005; // kurz und schmerzlos
        }
      }
    }
   t.used=len; //Längenanpassung
   t.addr=t.addr+len; //Adressanpassung
   i2c.stop(); //Vorgang beendet, Bus ist frei
   release; //readbytearray ist fertig,
  }
}

/*************************************/
/* Byte-Array schreiben              */
/*************************************/
function writebytearray (t_EE_addr t, byte data[], int len,byte f)
{
int i,j; //counter für Array
 capture i2c.flag; //writebytearray darf niemals mehrfach ausgeführt werden
  wait i2c.ready(); //wartet auf Busfreigabe und auf EEPROM aus Memorymap
  wait i2c.start(160 or EEmmap[(t.addr and 262143) shr 16]);
  i2c.write(t.addr shr 8); //schreibt Adresse im selektierten EEPROM
  i2c.write(t.addr);
  for i=0 ... len-1 //schreibvorgang des Array data[]
   {
    if f and EEpw[DoCRC] == EEpw[DoCRC] //ggf. CRC berechnen
     {
      for j = 7 ... 0 step -1 //msb zuerst... in asm wäre das schöner
      {
        if ((t.crc and 32768)==32768) xor ((data[i] and EEpw[j])==EEpw[j])
         if f and EEpw[CRC16]==EEpw[CRC16] t.crc=((t.crc and 32767) shl 1) xor 0x1021;
         else t.crc=((t.crc and 32767) shl 1) xor 0x8005; // kurz und schmerzlos
      }
     }
    i2c.write(data[i]); //schreiben
    if (t.addr+i+1 % EEblock)==0 //Pagebreak gefunden
     {
       i2c.stop(); //Pagebreak -> stop
       wait i2c.ready(); //Pagebreak ausführen -> neue Bank/EEPROM einleiten
       wait i2c.start(160 or EEmmap[(t.addr+i+1 and 262143) shr 16]);
       i2c.write(t.addr+i+1 shr 8); //schreibt Adresse im neu selektierten EEPROM
       i2c.write(t.addr+i+1); //von nun an kann es normal weiter gehen
     }
   }
  t.used=len; //Längenanpassung
  t.addr=t.addr+len; //Adressanpassung
  i2c.stop(); //Vorgang beendet, Bus ist frei
  release; //writebytearray ist hier fertig
  if f and EEpw[DoV]==EEpw[DoV] verifybytearray(t,data,len,f);
}

/*************************************/
/* einzelnes Byte lesen              */
/*************************************/
function readbyte (t_EE_addr t,byte f) returns byte
{
byte buffer[0];
  readbytearray (t, buffer,1,f);
  t.used=1;
  return buffer;
}

/*************************************/
/* einzelnes Integer lesen           */
/*************************************/
function readint (t_EE_addr t,byte f) returns int
{
byte buffer[1];
  readbytearray (t, buffer,2,f);
  t.used=2;
  return mem.getint(buffer,0);
}

/*************************************/
/* einzelnes long lesen              */
/*************************************/
function readlong (t_EE_addr t,byte f) returns long
{
byte buffer[3];
  readbytearray (t, buffer,4,f);
  t.used=4;
  return mem.getlong(buffer,0);
}

/*************************************/
/* einzelnes float lesen              */
/*************************************/
function readfloat (t_EE_addr t,byte f) returns float
{
byte buffer[7];
  readbytearray (t, buffer,8,f);
  t.used=8;
  return mem.getfloat(buffer,0);
}

/*************************************/
/* Integer-Array lesen               */
/*************************************/
function readintarray (t_EE_addr t, int data[], int len,byte f)
{
int i;
byte buffer[1];
  for i=0 ... len
  {
    readbytearray (t, buffer,2,f);
    data[i]=mem.getint(buffer,0);
  }
  t.used=2*len;
}

/*************************************/
/* Long-Array lesen                  */
/*************************************/
function readlongarray (t_EE_addr t, long data[], int len,byte f)
{
int i;
byte buffer[3];
  for i=0 ... len
  {
    readbytearray (t, buffer,4,f);
    data[i]=mem.getlong(buffer,0);
  }
  t.used=4*len;
}

/*************************************/
/* Float-Array lesen                  */
/*************************************/
function readfloatarray (t_EE_addr t, float data[], int len,byte f)
{
int i;
byte buffer[7];
  for i=0 ... len
  {
    readbytearray (t, buffer,8,f);
    data[i]=mem.getfloat(buffer,0);
  }
  t.used=8*len;
}

/*************************************/
/* String lesen (32Byte)             */
/*************************************/
function readstr (t_EE_addr t, byte s[],byte f)
{
  readbytearray (t,s,32,f);
  t.used=32;
}

/*************************************/
/* einzelnes Byte schreiben          */
/*************************************/
function writebyte (t_EE_addr t, byte data,byte f)
{
  byte buffer[0]; // 1 Byte
  buffer = data;
  writebytearray (t, buffer,1,f);
  t.used=1;
}

/*************************************/
/* einzelnes Integer schreiben       */
/*************************************/
function writeint (t_EE_addr t, int data,byte f)
{
byte buffer[1]; // 2 Byte
mem.putint(buffer,0,data);
writebytearray (t, buffer,2,f);
t.used=2;
}

/*************************************/
/* einzelnes long schreiben          */
/*************************************/
function writelong (t_EE_addr t, long data,byte f)
{
byte buffer[3]; // 4 Byte
mem.putlong(buffer,0,data);
writebytearray (t, buffer,4,f);
t.used=4;
}


/*************************************/
/* einzelnes float schreiben          */
/*************************************/
function writefloat (t_EE_addr t, float data,byte f)
{
byte buffer[7]; // 8 Byte
mem.putfloat(buffer,0,data);
writebytearray (t, buffer,8,f);
t.used=8;
}

/*************************************/
/* Integer-Array schreiben           */
/*************************************/
function writeintarray (t_EE_addr t, int data[], int len,byte f)
{
int i;
byte buffer[1]; // 2 Byte
  for i=0 ... len
   {
     mem.putint(buffer,0,data[i]);
     writebytearray (t, buffer,2,f);
   }
   t.used=2*len;
}

/*************************************/
/* Long-Array schreiben              */
/*************************************/
function writelongarray (t_EE_addr t, long data[], int len,byte f)
{
int i;
byte buffer[3]; // 4 Byte
  for i=0 ... len
   {
     mem.putlong(buffer,0,data[i]);
     writebytearray (t, buffer,4,f);
   }
   t.used=4*len;
}

/*************************************/
/* Float-Array schreiben              */
/*************************************/
function writefloatarray (t_EE_addr t, float data[], int len,byte f)
{
int i;
byte buffer[7]; // 8 Byte
  for i=0 ... len
   {
     mem.putfloat(buffer,0,data[i]);
     writebytearray (t, buffer,8,f);
   }
   t.used=8*len;
}

/*************************************/
/* String schreiben (32Byte)         */
/*************************************/
function writestr (t_EE_addr t, byte s[],byte f)
{
  writebytearray (t,s,32,f);
  t.used=32;
}

/*************************************/
/* Muster für eine eigene Datentypen */
/*************************************/
/*
const ARRAYsize=255;

type mytype
{
  byte BYTE;
  int INT;
  long LONG;
  float FLOAT;
  string STRING;
  int ANYARRAY[ARRAYsize];
}

mytype abc;

function readmytype (t_EE_addr t, mytype abc,byte f)
{
 abc.BYTE=readbyte(t,f);
 abc.INT=readint(t,f);
 abc.LONG=readlong(t,f);
 abc.FLOAT=readfloat(t,f);
 readstr(t,abc.STRING,f);
 readintarray(t,abc.ANYARRAY,ARRAYsize,f);
}

function writemytype (t_EE_addr t, mytype abc,byte f)
{
 writebyte(t,abc.BYTE,f);
 writeint(t,abc.INT,f);
 writelong(t,abc.LONG,f);
 writefloat(t,abc.FLOAT,f);
 writestr(t,abc.STRING,f);
 writeintarray(t,abc.ANYARRAY,ARRAYsize,f);
}

/--------------------------------------------------------/
Beispiel für eine geänderte Stringfunktion incl. CRC
der 16 Bit CRC-Wert wird in AnschluÃ? an den String
geschrieben, lesend kann der Wert dann verglichen werden.
/--------------------------------------------------------/
function writestr (t_EE_addr t, byte s[],byte f)
{
  writebytearray (t,s,32,f);
  writelong(t,t.crc,f or ModCRC);
  t.crc=0
}
/--------------------------------------------------------/
*/

/*
//Typische Anwendung (als Beispiel)
thread main
{
int testarray[399];
long a;
//initialisiere Array testarray[399]; mit Daten, eigener Code
   t_EE_addr myaddress;
   init();
   setaddr(48000,myaddress); //Möglichkeit 1 um Startadresse zu setzen
   writeintarray(myaddress,testarray,399,default);
   //writeintarray(48000,testarray,399,default); //Dies geht nicht!
   //writeintarray(setaddr(48000,myaddress),testarray,399,default);//Dies geht nicht!
   //lösche Array testarray[]; eigener Code
   myaddress.addr=48000; //Möglichkeit 2 um Startadresse zu setzen
   readintarray(myaddress,testarray,399,default); //zurücklesen
   a=setaddr(48000,myaddress)+500; // a ist 48500, nächster Vorgang ab 48000
   writelong(myaddress,a,DoV); //schreibt a nach 48000 mit Verify
   writelong(myaddress,a,DoCRC+CRC16); //schreibt a nach 48004 mit CRC16
   writeint(myaddress,myaddress.crc,default); //schreibt crc-Wert nach 48008
   a=oldaddr(50000,myaddress); // alter Addresswert wird in a zurück gegeben.
   // a hat nun 480010, der aktuelle Pointer liegt auf 50000
   // weitere Vorgänge...
   a=setaddr(a,myaddress); // der aktuelle Pointer liegt wieder auf 48010
   writeint(myaddress,a,DoV); //Schreibt a nach 48010 mit verify
   // über t_EE_addr variable; können verschiedene Pointer verwaltet
   // und mit setEEaddr und getEEaddr komfortabel bearbeitet werden
   // Unabhängig laufende Schreib/Lesepointer sind leicht einzusetzen.
   // Beispiel....
   t_EE_addr readptr;
   t_EE_addr writeptr;
   cpyaddr(readptr,writeptr); //copy der Ptr von readptr nach writeptr
   // Addressen neu setzen...
   setaddr(48000,readptr);
   setaddr(49000,writeptr);
   for a=0...9 //copy von 10 Int-Arrays[9] von 48000 nach 49000
   {
      readintarray(readptr,testarray,10,default);
      writeintarray(writeptr,testarray,10,DoCRC);
   }
   writeint(myaddress,writeptr.crc,DoV); //schreibt crc32-Wert als AbschluÃ?
   // über die ganzen Schreibvorgänge aus der for-Schleife mit Verify.
   // Nun können die Arrays wieder eingelesen und gegen die CRC-Summe
   // geprüft werden. Es wäre möglich, die beiden CRC's zu vergleichen
   // um Verarbeitungsfehler auszuschlieÃ?en. Allerdings dann mit DoCRC bei read.
   setaddr(49000,readptr); //***
   for a=0...9 //einlesen der eben kopierten Arrays
      readintarray(readptr,testarray,10,DoCRC);
   if readptr.crc != writeptr.crc DoError(readptr); //CRC-Fehler, Daten wurden
   //offensichtlich modifiziert. DoError sollte darauf passend reagieren.
   setaddr(49000,readptr); //Ersatzweise als Vergleich zu ***
   for a=1...8 //zeilweise einlesen der eben kopierten Arrays
      readintarray(readptr,testarray,10,DoCRC);
   if readptr.crc != writeptr.crc DoError(readptr); // CRC-Fehler erzwungen.
   // Hier muÃ? ein CRC-Fehler auftreten da nicht alle CRC-relevanten Daten
   // verarbeitet wurden.
}
*/



GruÃ? Rolf





    Antwort schreiben


Antworten: