Forum: Mikrocontroller und Digitale Elektronik Speichergröße der Smart Cards mit dem AT24C von Atmel bestimmen


von Daniel H. (daniel_h27)


Lesenswert?

Hallo zusammen,

ich stehe vor dem Problem, die Speichergröße der SmartCards mit AT24C 
EEPROMs zu bestimmen.

Funktionsweise der Chips folgendermaßen:
- Lesen/Schreiben via I2C
- Direktes Lesen der Speichergröße nicht möglich
- Wenn von einer Adresse oberhalb des Speicherbereichs gelesen wird, 
wird wieder ab Adresse 0 begonnen (höherwertige Bits werden ignoriert)

Zur Zeit haben wir für unser Gerät einen käuflich erworbenen Kartenleser 
im Einsatz, der das kann. Nun soll ein Kartenleser integriert werden, 
der die Karten liest. Der funktioniert soweit einwandfrei. Nur leider 
kann er die Kartengröße nicht bestimmen.

Hat jemand ne Idee?

Danke

Gruß

Daniel

von You (Gast)


Lesenswert?

Daniel H. schrieb:
> - Wenn von einer Adresse oberhalb des Speicherbereichs gelesen wird,
> wird wieder ab Adresse 0 begonnen (höherwertige Bits werden ignoriert)


Das ist doch schon die Lösung. Du schaust einfach nach, bei welcher 
Adresse dieser Wrap-Around stattfindet, dann hast du die verfügbare 
Speicherkapazität.

von Eumel (Gast)


Lesenswert?

Und wie soll man den Wrap-Around feststellen?

von Daniel H. (daniel_h27)


Lesenswert?

Und wie soll man den Wrap-Around feststellen? Genau das ist die Frage: 
Woher willst du wissen, ob du bspw. bei Adresse 0x8000 tatsächlich von 
Adr 0x8000 oder von Adresse 0x0000 liest. Du weißt ja nicht, ob hier Bit 
15 ignoriert wird (wrap-around) oder nicht (richtig adressiert).

Meines Erachtens ist es ohne Veränderung der Daten (Schreiben) nicht 
möglich.

von eProfi (Gast)


Lesenswert?

Das geht mit dem sequential read.
Beschreibe das ganze SEEPROM (oder nur die kritischen Stellen 007F, 
00FF, 01FF, 03FF, 07FF) z.B. mit 00 oder 55 und die höchstmögliche 
Adresse anders (z.B. FF oder AA).
Dann beginnst Du bei Adr 0000 sequentiell zu lesen und findest 
irgendwann das "andere" Byte (mitzählen).

von eProfi (Gast)


Lesenswert?

Vor dem Schreiben die veränderten Werte speichern und nach dem Test 
zurückschreiben.

Wenn Du nicht schreiben willst, kannst Du auch die Inhalte vergleichen.
Wenn er sich z.B. alle 1kB wiederholt, dürfte es sich um eine 1kB-Karte 
handeln.
Ist nicht 100% sicher (es könnte ja tatsächlich mehrmals das gleiche 
hintereinander drinstehen).

Um welche Kartengrößen geht es denn?

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

eProfi schrieb:
> Beschreibe das ganze SEEPROM (oder nur die kritischen Stellen 007F,
> 00FF, 01FF, 03FF, 07FF) z.B. mit 00 oder 55 und die höchstmögliche
> Adresse anders (z.B. FF oder AA).

Die AT24Cxxx EEPROMs unterscheiden sich allerdings je nach Kapazität in 
ihrer Adressierung.

von Der (Gast)


Lesenswert?

Kannst du nicht die Adresse des letzten Zugriffs auslesen? Mit Adresse 
meine ich wirklich die Adresse, nicht den Inhalt an dieser Adresse.

von Daniel H. (daniel_h27)


Lesenswert?

Danke für die Antworten

@eProfi:
Die "Schreibende"-Lösung hat zwei Nachteile. Die "Test"-Zellen werden 
unnötig belastet (Schreib-/Lese-Zyklus) und sollte die Karte gezogen 
werden, bevor ich den Wert restauriert habe, sind die Kartendaten 
unbrauchbar.
Inhalte vergleichen ist bei einer Rohkarte (alle Zellen 0xff) nicht 
möglich.
Kartengrößen sind At24C 01, 02, 04, 08, 16, 32, 64, 128, 256, 512

@Magnus:
Das ist nicht ganz richtig. Die Karten At24C 01, 02, 04, 08, 16 werden 
mit 11-bit adressiert. Die Karten At24C 32, 64, 128, 256, 512 mit 
16-bit. Es ist also lediglich möglich zu Unterscheiden, obs ne 11-bit 
bzw. ne 16-bit Karte ist.

@Der:
Leider kann man die Adresse des letzten Zugriffs nicht auslesen. Man 
kann sie nur setzen.

von weinbauer (Gast)


Lesenswert?

wenn du hingehst, die ersten 3 Bytes der Karte unbenutzt lässt und da 3 
definierte Zeichen reinschreibst 7F 7F 7F, dann musst Du nur die 
Endwerte+3 adressieren und auslesen, stehen da dann Deine definierten 3 
Bytes, dann ist das der wrap around und Du hast die Größe.

von Daniel H. (daniel_h27)


Lesenswert?

@weinbauer:
gute idee. nur leider ist das Format der Karte aus der Vergangenheit 
vorgegeben

von Peter D. (peda)


Lesenswert?

Wenn die Daten nicht ein bekanntes Format haben, ist ein Erkennen ohne 
Schreiben nur bei den Typen 04, 08 und 16 möglich.


Peter

von Daniel H. (daniel_h27)


Lesenswert?

Hallo zusammen,

habs folgendermaßen gelöst:
- Es wird die jew. letzte Adresse gelesen 0xffff, 0x7fff, 0x3fff, 
0x1fff, 0x0fff
- Es wird geprüft, ob in der letzten Adresse unterschiedliche Werte 
drinstehen
- Sollten gleiche Werte drinstehen, dann muss ich prüfen, ob ein wrap 
around stattgefunden hat oder wirklich gleiche Werte drinstehen; das 
geht natürlich nicht ohne die Zelle zu verändern (der Wert wird 
anschließend wieder restauriert)
1
UI32 I2C_Test16bitAddress()
2
   {
3
   UI8 specialBytes[5];
4
   UI8 temp,temp_inv,temp_p1;
5
   int i;
6
   UI32 maxsize=0x10000; // 512K = 65536 Bytes
7
   UI32 minsize_index=4;
8
9
   // 1) Lesen der jew. letzen Adresse (von allen 5 Speicherstellen 0xffff, 0x7fff, 0x3fff, 0x1fff, 0x0fff)
10
11
   printd("\nLESEN\n");
12
   for (i=0;i<5;i++)
13
      {
14
      I2C_TestReadByte((0xffff>>i),&specialBytes[i]);
15
      printd("Byte%i [%xi] = %xi\n",i,(0xffff>>i), specialBytes[i]);
16
      }
17
   // 2)  Prüfung 1 - Minimalgröße ohne Schreiben bestimmen
18
19
   printd("\nPRÜFUNG 1\n");
20
   for (i=0;i<4;i++)
21
      {
22
      if (specialBytes[i+0] != specialBytes[i+1]
23
          // Speicherzellen sind nicht gleich?
24
         )
25
         {
26
27
         // Ja -> mein Speicher ist min (maxsize>>i) Bytes groß
28
         printd("min. %i Bytes (1)\n",(maxsize>>i));
29
         minsize_index = i;
30
         break;
31
32
         }
33
      else
34
         {
35
         // Nein -> weiter gehts
36
         }
37
      }
38
   // 3) Prüfung 2 - ab Minimalgröße bis Maximalgröße schreibend prüfen
39
40
   printd("\nPRÜFUNG 2\n");
41
   for (i=0;i<minsize_index;i++)
42
      {
43
      temp_inv = ~(specialBytes[i+0]);
44
      temp     =   specialBytes[i+0];
45
46
      printd("Byte%i : %xi wird zu %xi\n",i,temp,temp_inv);
47
48
      I2C_TestWriteByte((0xffff>>i), temp_inv); // inv. Wert an letzte Adresse schreiben
49
      I2C_TestReadByte ((0x7fff>>i), &temp_p1); // letzte Adresse/2 erneut lesen
50
      I2C_TestWriteByte((0xffff>>i), temp    ); // orig. Wert an letzte Adresse zurückschreiben
51
      if (temp_p1 != temp_inv
52
          // Ist nicht der inv. Wert in beiden Zellen?
53
         )
54
         {
55
         // Ja -> es ist ein (maxsize>>i) großer Speicher
56
57
58
         printd("%i Bytes (2)\n",(maxsize>>i));
59
         I2C_BlockCount=(maxsize>>(i+9));
60
         return OK;
61
62
         }
63
      else
64
         {
65
         // Nein -> es ist KEIN (maxsize>>i) großer Speicher
66
         }
67
      }
68
69
   return NOK;
70
71
   }

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.