Speichergröße der Smart Cards mit dem AT24C von Atmel bestimmen

OP #2906344
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
Gast #2906357
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.
OP #2906378
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.
Gast #2906714
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).
Gast #2906728
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?
OP #2907062
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.
Gast #2907114
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.
OP #2907622
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
   }

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.