Hallo Leute, ich habe ein EEPROM mit 4Kbit von ST im Einsatz. Die genaue Bezeichnung lautet ST24c04, siehe Datenblatt im Anhang. Beschaltet ist es folgendermaßen: SDA, SCLK entsprechd mit Pullups an µC. Vcc und Mode an 3,3V. Vss, E1, E2 und PRE auf Masse. Wenn ich als BlockSelect-Bit 0 wähle, dann die 256Byte beschreibe und anschließend auslese, stimmen die Werte. Wähle ich die oberen 256Byte, dann stimmen die Werte nicht mehr. Laut Oszi werden die richtigen Daten übertragen beim Beschreiben, auch die ACKs kommen. Zwischen den jeweiligen Schreibzyklen wird 10ms gewartet gemäß tw im Datenblatt. Das komische ist eben, dass das nur bei den ersten 256Byte auftritt. Hat jemand eine Idee woran es liegen könnte? Ich habe auch schon mehrere EEPROMs der gleichen Version ausprobiert. Vielen Dank.
>Hat jemand eine Idee woran es liegen könnte? Ich habe auch schon mehrere >EEPROMs der gleichen Version ausprobiert. Das liegt an deinem Programm.
Jo, das wär natürlich noch ne Möglichkeit. Komisch ist eben nur, dass es beim ersten Block dann reibungslos funktioniert. Was ich noch nachtragen muss: Wenn ich den zweiten Block mit 0x00 beschreibe, stimmts. Ich lese anschließend wirklich auf 0x00 aus. Mit dem Oszi überprüft. Hat jemand schonmal was ähnliches gehabt? Gerade beim ST.?
>Jo, das wär natürlich noch ne Möglichkeit. Möglichkeit? Du hast ein Softwareproblem;) >Hat jemand schonmal was ähnliches gehabt? Gerade beim ST.? Nö, kann immer locker vom Anfang bis zum Ende programmiert werden. Hardwarefehler haben die nicht. Der Fehler liegt wie immer in Zeile 42 oder sitzt vor dem Bildschirm.
Wenn du das erste Byte beider Hälften mit einem unterschiedlichen Inhalt beschreibst, wobei das weder lauter Nullen noch lauter Einsen sein sollten, was steht dann hinterher drin?
ALso, habe jeweils das erste Byte jedes Blcoks mit 0x57 beschrieben. Erster Block stimmt, ich lese 0x57. Beim zweiten Block lese ich 0x47.
Im Anhang mal noch die Oszibilder beim jeweiligen Vorgang. Beim Lesen wird in der Mitte ungefähr eine wiederholter Start eingeleitet. Alles wird richtig "ge-ackt" und auch am Ende des Lesens kommt ein NAK.
Schön. Jetzt bräuchte man bloß noch einen Timing nach C-Code Umsetzer. Peter
1 | int Test_EEPROM (void) |
2 | {
|
3 | unsigned char eeprom_data; |
4 | unsigned int address; |
5 | int error_count = 0; |
6 | |
7 | // Block 0 beschreiben
|
8 | for (address = 0, eeprom_data = 0x00; address <= 0xff; address++, eeprom_data++) |
9 | {
|
10 | EEPROM_Write (EEPROM_1, Block_0, address&0xFF, 1, (u8*)&eeprom_data); |
11 | }
|
12 | |
13 | // Block 1 beschreiben
|
14 | for (address = 0, eeprom_data = 0x00; address <= 0xff; address++, eeprom_data++) |
15 | {
|
16 | EEPROM_Write (EEPROM_1, Block_1, address&0xFF, 1, (u8*)&eeprom_data); |
17 | }
|
18 | |
19 | eeprom_data = 0; |
20 | // Block 0 lesen
|
21 | for (address = 0; address <= 0xff; address++) |
22 | {
|
23 | eeprom_data = (unsigned char)EEPROM_Read (EEPROM_1, Block_0, address&0xFF, 1); |
24 | if (eeprom_data != address) |
25 | {
|
26 | error_count++; |
27 | }
|
28 | }
|
29 | |
30 | eeprom_data = 0; |
31 | // Block 1 lesen
|
32 | for (address = 0; address <= 0xff; address++) |
33 | {
|
34 | eeprom_data = (unsigned char)EEPROM_Read (EEPROM_1, Block_1, address&0xFF, 1); |
35 | // eeprom_data = *pTWI_RCV_DATA8;
|
36 | |
37 | if (eeprom_data != address) |
38 | {
|
39 | error_count++; |
40 | }
|
41 | }
|
42 | |
43 | return error_count; |
44 | }
|
45 | |
46 | void EEPROM_Write (u8 eeprom, u8 block, u8 address, u8 datasize, u8 *data) |
47 | {
|
48 | do
|
49 | {
|
50 | if (*pTWI_MASTER_STAT & ANAK) |
51 | *pTWI_MASTER_STAT |= ANAK; // Adress-NAK-Bit zurücksetzen |
52 | xmt = 0; |
53 | mcomp = 0; |
54 | |
55 | TWI_TxPtr = data; // Pointer auf Daten |
56 | *pTWI_XMT_DATA8 = address; // Adresse in FIFO laden |
57 | EEPROM_Select (eeprom, block); // EEPROM auswählen, hierzu müssen Daten im FIFO sein, ansonsten Fehler (siehe HW_Ref) |
58 | TWI_Write (datasize + 1); // Tx beginnen |
59 | |
60 | while((*pTWI_MASTER_STAT & BUSBUSY) || (*pTWI_MASTER_STAT & MPROG)); // Auf Tx_Ende warten |
61 | |
62 | TWI_Next_Cycle = 0; |
63 | while(!TWI_Next_Cycle); // 10ms warten -> EEPROM Write Time! |
64 | |
65 | }while(*pTWI_MASTER_STAT & ANAK); // Bei Adress-NAK nochmals versuchen |
66 | |
67 | }
|
68 | |
69 | |
70 | |
71 | int EEPROM_Read (u8 eeprom, u8 block, u8 address, u8 datasize) |
72 | {
|
73 | unsigned char Rx_Data = 0; |
74 | |
75 | Restart_bytes_to_read = datasize; |
76 | Restart_Flag = 1; |
77 | |
78 | *pTWI_XMT_DATA8 = address; // Adresse in FIFO laden |
79 | EEPROM_Select (eeprom, block); // EEPROM auswählen, hierzu müssen Daten im FIFO sein, ansonsten Fehler (siehe HW_Ref) |
80 | TWI_Write (1); // Tx beginnen |
81 | TWI_RxPtr = (u8*)&Rx_Data; |
82 | |
83 | TWI_Next_Cycle = 0; |
84 | while(!TWI_Next_Cycle); |
85 | while((*pTWI_MASTER_STAT & BUSBUSY) || (*pTWI_MASTER_STAT & MPROG)); // Auf Tx_Ende warten |
86 | |
87 | return Rx_Data; |
88 | }
|
89 | |
90 | // Und hier die ISR
|
91 | // TWI
|
92 | if (*pSIC_ISR & IRQ_TWI) |
93 | {
|
94 | |
95 | if (*pTWI_INT_STAT & MCOMP) // Transfer Complete |
96 | {
|
97 | *pTWI_INT_STAT |= MCOMP; // Clear Interrupt |
98 | |
99 | if (*pTWI_MASTER_CTL & RSTART) |
100 | {
|
101 | *pTWI_MASTER_CTL &= ~RSTART; |
102 | Restart_Flag = 0; |
103 | *pTWI_MASTER_CTL |= ((Restart_bytes_to_read) << 6); |
104 | }
|
105 | |
106 | mcomp++; |
107 | }
|
108 | |
109 | if (*pTWI_INT_STAT & XMTSERV) // Transfer IRQ |
110 | {
|
111 | if ((*pTWI_MASTER_CTL & DCNT) > 40) // Load next data if DCNT is > 1 |
112 | *pTWI_XMT_DATA8 = *TWI_TxPtr++; // Otherwise data transfer will be completed in next cycle |
113 | |
114 | |
115 | if (((*pTWI_MASTER_CTL & DCNT) == 0) && (Restart_Flag == 1)) |
116 | {
|
117 | *pTWI_MASTER_CTL |= RSTART; |
118 | *pTWI_MASTER_CTL |= MDIR; |
119 | }
|
120 | *pTWI_INT_STAT |= XMTSERV; // Clear Interrupt |
121 | xmt++; |
122 | |
123 | }
|
124 | |
125 | if (*pTWI_INT_STAT & MERR) |
126 | {
|
127 | *pTWI_INT_STAT |= MERR; // Clear Interrupt |
128 | merr = *pTWI_MASTER_STAT; // Save Master Status |
129 | }
|
130 | |
131 | |
132 | if (*pTWI_INT_STAT & RCVSERV) // Read IRQ |
133 | {
|
134 | *pTWI_INT_STAT |= RCVSERV; // Clear Interrupt |
135 | *TWI_RxPtr++ = *pTWI_RCV_DATA8; // Save received Byte |
136 | rcv++; |
137 | }
|
138 | |
139 | |
140 | |
141 | ssync(); |
142 | }
|
Das ganze läuft auf einem BlackFin.
Das wundert mich nicht, daß es nicht funktioniert. Du hast ne Menge zusätzlicher Fehlermöglichkeiten (Interrupt, HW-I2C). Machs erstmal zu Fuß (SW-I2C, keine Interrupts). Außerdem fehlen Funktionen, z.B. EEPROM_Select. Quelltexte als Anhang mit allem zum Compilieren nötigem! Peter
Ok, aber kann ich davon ausgehen, dass das Schreiben funktioniert, oder.
Michl schrieb: > Ok, aber kann ich davon ausgehen, dass das Schreiben funktioniert, oder. Das könntest du, wenn sich mit einem anderen bekannt funktionsfähigen I2C-Interface der Inhalt verifizieren liesse.
>Ok, aber kann ich davon ausgehen, dass das Schreiben funktioniert
Ich glaube das ehrlich gesagz nicht. Vermutlich schreibst du immer
in den Block 0.
Was macht denn dein EEprom_Select genau?
Du weist wie bei den EEproms >256 Bytes die Blöcke addressiert werden?
Thomas
Michl schrieb: > Ok, aber kann ich davon ausgehen, dass das Schreiben funktioniert, oder. Weiß ich nicht, ich kenne das TWI und den Interruptcontroller Deines MC nicht. Du weißt aber schon, daß man immer nur ein Byte oder eine Page schreiben kann? Peter
Mein EEPROM_Select setzt die Adresse des EEPROMS zusammen. Also 0b1010 und dann eben 0b00hintendran für die hardwired Adresse sowie eine 0 für Block 0 bzw. eine 1 für Block 1 hinten dran. Ergo: Block 0 = 0b1010000 Block 1 = 0b1010001 Das kommt ja auch raus laut Oszi.
Bei diesem EEPROM kann man auch noch MultiByte schreiben -> siehe Datenblatt, MODE-Pin. Dann sinds 4 Byte.
Wenn ich von Adresse 0x00 bis 0xFF den jweiligen Adresswert reinschreib, also 0x00 auf 0x00, 0x5a auf 0x5a usw, dann ergibt sich folgendes "Bild": Adresse Daten x0 00 x1 x1 x2 x2 x3 x3 x4 x4 x5 x5 x6 x6 x7 x7 x8 x8 x9 x9 xa xa xb xb xc xc x1 x1 <-- falsch x2 x2 <-- falsch xf xf
Habe das EEPROM mal mit einem externen Lesegerät ausgelesen. Werte werden korrekt geschrieben. Also liegts am Lesen, wobei die Adressen stimmen laut Oszi. Ominös iwie...
Ich habe das Problem immer noch. Kann jmd. die Leseübertragung anhand der Oszi-Bilder und des Datenblatts verifizieren? Meiner Meinung nach stimmt was ich LESE und ÜBERTRAGEN wird.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.