Mich würde Eure Meinung interessieren:
Habe hier 2 25LC1024 SPI EEPROMs, 128 KBytes. Zu meiner Schande muss ich
gestehen, dass ich die bei Ebay aus China erworben habe (glaube ich
zumindest - inzwischen kaufe ich direkt bei Microchip oder Mouser), da
ich keine einfachere Quelle wusste damals.
Die funktionieren zwar, *aber*:
- der eine macht beim Schreiben bei Page 256 schlapp, und sollte doch
bis Page 512 gehen! 512 * 256 Page Size = 128 KBytes.
- der andere machte schon bei Page 4 schlapp!!
Schlussfolgerung: entweder sind die beiden defekt, oder wurden
umgelabelt (25LC640, 25LC512). Macht das überhaupt Sinn?? Die sehen 100%
authentisch aus, wie die funktionierenden 25LC1024.
Ich habe eine Schaltung zum Testen / Speichertest - ja, Hardware /
Software-Fehler kann ich ausschließen :-) Im EEPROM-Tester laufen 3
andere 25LC1024 vollständig durch (alle Seiten von 0 bis 512 werden
einwandfrei geschrieben und wieder ausgelesen), währen es mit den beiden
obigen 25LC1024 eben die oben beschriebenen Probleme gibt.
Macht es überhaupt Sinn, 25LC.... zu fälschen?? Oder sind die einfach
defekt? Hat schon mal einer von Euch sowas gehabt?
Michael W. schrieb:> - der eine macht beim Schreiben bei Page 256 schlapp, und sollte doch> bis Page 512 gehen! 512 * 256 Page Size = 128 KBytes.
Könnte man mit STATUS:BP=1 erklären..
> - der andere machte schon bei Page 4 schlapp!!
..das aber nicht ..
Ob sie umgelabelt sind, kann man ganz einfach feststellen.
Der 1024 benötigt 3 Adreßbytes und aktiviert dann erst SO.
Ist es ein kleinerer, geht SO schon nach 2 Adreßbytes von Hochohmig auf
Ausgang.
nvmem schrieb:> Michael W. schrieb:>>> - der eine macht beim Schreiben bei Page 256 schlapp, und sollte doch>> bis Page 512 gehen! 512 * 256 Page Size = 128 KBytes.>> Könnte man mit STATUS:BP=1 erklären..
Ja, die Idee hatte ich auch schon... habe daher ArrayProtection (WRSR)
auf 0 gesetzt... und auch alles gelöscht (Clear Chip). Kein
Unterschied.
1
voidEEPROM_disableWriteProtection(void){
2
SLAVE_SELECT;
3
SPI_tradeByte(EEPROM_WRSR);
4
SPI_tradeByte(0);// no write protection at all, all blocks writeable!
Mir erklärte ein Distri,
dass verschiedene ICs in den chinesischen Firmen gefertigt würden und
in eine große Kiste nach dem Fertigungsprozess fallen.
Danach kommt der Qualitätscheck des Auftraggebers.
Die Guten kommen in die grüne Kiste, die anderen in die rote Kiste.
Die grüne Kiste bekommt der "Auftraggeber", die rote Kiste wird
an "Schwarzhändler" verscherpelt.
Es ist aber nicht gesagt, dass die II. Wahl nicht funktionieren könnte.
Enstpricht nur nicht der vollen Spezifikation oder kann natürlich auch
totaler Schrott sein. Abnehmer gäbe es genügend.
A. B. schrieb:> Was sagt das RDID-Kommando? Die ID zu fälschen wär' schon etwas> aufwändiger.
Der Code ist 41, bei allen... ich hätte auf 42 gewettet :D Es scheint
also keine Fälschung zu sein.
Ist denn 41 die richtige Kennung für einen 25LC1024?
Das Problem ist nämlich nach wie vor, dass ich nur 64 KBytes addressiert
kriege... mit ALLEN 25LC1024 die ich habe.
Ich hatte doch noch einen Fehler in meinem Test-Code, da
EPROM_disableWriteProtection nie ausgeführt wurde. Jetzt wurde es
ausgeführt, und alle EEPROMS verhalten sich gleich - super! Und ich kann
tatsächlich alle EEPROMs von 0x00000 bis 0x1ffff beschreiben.
Allerdings klappt das Beschreiben nach wie vor nicht für 0x10000 bis
0x1ffff - diese werden nämlich auf 0x00000 - 0x0ffff "umgebogen".
m.a.W., das 3. Address-Byte in der 24 Bit-Addresse wird ignoriert:
1
voidEEPROM_send24BitAddress(uint32_taddress){
2
3
SPI_tradeByte((uint8_t)address>>16);
4
SPI_tradeByte((uint8_t)address>>8);
5
SPI_tradeByte((uint8_t)address);
6
7
}
Beim Lesen mittels
1
uint8_tEEPROM_readByte(uint32_taddress){
2
SLAVE_SELECT;
3
SPI_tradeByte(EEPROM_READ);
4
EEPROM_send24BitAddress(address);
5
SPI_tradeByte(0);
6
SLAVE_DESELECT;
7
return(SPDR);
8
}
kriege ich also das gleiche Byte, egal ob 0x1abcd oder 0x0abcd
Beschrieben hatte ich den Speicher im Page-Mode, mit Page Size = 256.
Ich hatte auch schon daran gedacht, dass ich irgendwo nen
Variablen-Überlauf habe (16 Bit oder signed oder...), aber ALLE meine
Variablen die mit EEPROM-Addressen zu tun haben (in C), sind uint32_t.
Hmm.... bin ratlos.
Lösche den EEPROM und schreibe nur was in die erste Page.
Und dann lies ihn komplett hintereinander aus. Dann wirken sich Fehler
in Deiner Adressierung nicht aus, da der EEPROM ja intern hochzählt.
Peter D. schrieb:> Lösche den EEPROM und schreibe nur was in die erste Page.> Und dann lies ihn komplett hintereinander aus. Dann wirken sich Fehler> in Deiner Adressierung nicht aus, da der EEPROM ja intern hochzählt.
Guter Tipp, werde ich machen! Danke! So werde ich rauskriegen, ob es
tatsächlich nur 64 KB hat...
Michael W. schrieb:> Der Code ist 41, bei allen... ich hätte auf 42 gewettet :D Es scheint> also keine Fälschung zu sein.> Ist denn 41 die richtige Kennung für einen 25LC1024?
Was sagt denn das Datenblatt? 0x29, also 32+9, passt!
Lothar M. schrieb:> Michael W. schrieb:>> Der Code ist 41, bei allen... ich hätte auf 42 gewettet :D Es scheint>> also keine Fälschung zu sein.>> Ist denn 41 die richtige Kennung für einen 25LC1024?> Was sagt denn das Datenblatt? 0x29, also 32+9, passt!
Ah, das war durchgerutscht beim Lesen. Ich hatte nach der Id gesucht im
Datenblatt, allerdings ist mir nicht aufgefallen, dass die "im Bild
versteckt war". Danke!
Michael W. schrieb:> ja, Hardware /Software-Fehler kann ich ausschließen
Warum hast du denn dann überhaupt weitergemacht? Die einzige sinnvolle
Schlussfolgerung daraus wäre doch gewesen: die Dinger sind nicht in
Ordnung.
:-)
H.Joachim S. schrieb:> Michael W. schrieb:>> ja, Hardware /Software-Fehler kann ich ausschließen>> Warum hast du denn dann überhaupt weitergemacht? Die einzige sinnvolle> Schlussfolgerung daraus wäre doch gewesen: die Dinger sind nicht in> Ordnung.>> :-)
Tja... warum nun einige der 25LC1024 mit gesetzten Schutzbits hier
ankamen, und andere nicht, ist mir ein Rätsel! War mir nicht klar, dass
man die sozusagen erst bereinigen muss. Das wurde in keinem der Artikel,
die ich gelesen hatte, erwähnt... und von den C-Beispielen, die ich mir
angesehen habe, verwendet ebenfalls keiner die EEPROM_WRSR Instruction.
Jetzt hoffe ich, dass wir das verbleibende Rätsel auch noch gelöst
kriegen! :-)
Michael W. schrieb:> Tja... warum nun einige der 25LC1024 mit gesetzten Schutzbits hier> ankamen, und andere nicht, ist mir ein Rätsel!
Vermutlich sind die dann recycled worden und haben schon ein paar
Schreibzyklen hinter sich...
Peter D. schrieb:> Lösche den EEPROM und schreibe nur was in die erste Page.> Und dann lies ihn komplett hintereinander aus. Dann wirken sich Fehler> in Deiner Adressierung nicht aus, da der EEPROM ja intern hochzählt.
OK, ich habe den Chip geloescht, alle Bytes sind danach 255. Dann habe
ich an Adresse 0 das Byte 123 geschrieben. Nun alles ausgelesen und
gezaehlt, bis ich 123 zurueckgelesen habe. Ergebnis: es sind
tatsaechlich 128 KB.
Nun frage ich mich natuerlich, ob der Fehler in der Addressierung beim
Schreiben oder beim Lesen entsteht. Ich schreibe die Daten naemlich
Seiten-Weise (CS LO, Write Enable, CS HI, CS LO, Write Instruction,
Page-Anfangsaddresse, dann die 256 Bytes senden, dann CS HI).
Ich werde einmal auf Seiten-weises Schreiben verzichten, und jeder Byte
mit Addresse senden zum Schreiben.
A. B. schrieb:> Michael W. schrieb:>> SPI_tradeByte((uint8_t) address >> 16 );>> SPI_tradeByte((uint8_t) address >> 8 );>> SPI_tradeByte((uint8_t) address );>> Schon mal mit>> SPI_tradeByte((uint8_t) (address >> 16));> SPI_tradeByte((uint8_t) (address >> 8));> SPI_tradeByte((uint8_t) address );>> probiert?
Sorry, das war ein Copy & Paste Fehler... ich habe tatsächlich sowas wie
1
voidEEPROM_send24BitAddress(uint32_taddress){
2
3
SPI_tradeByte((uint8_t)((address>>16)&1));
4
SPI_tradeByte((uint8_t)((address>>8)&255));
5
SPI_tradeByte((uint8_t)(address&255));
6
7
}
im Code, schon von Anfang an, doch habe das hier aus dem Gedächtnis
gepostet, und dabei ist mir aufgefallen, dass &1, &255 etc. redundant
sind. Dabei habe ich hier die Klammern ommitted... die sind allerdings
nach wie vor im Code. Sorry für die Verwirrung!
Also, das ist es leider nicht. Danke für's Mitdenken!!!
Hier ist mein Test-Programm - das findet keine Fehler, was ein gutes
Zeichen ist. Allerdings kriege ich immer noch das beschriebene Verhalten
in meinem anderen Programm-Abschnitt; muss sehen, woran das liegt. Es
scheint also etwas anderes zu sein - das EEPROM ist OK, und funktioniert
wie es soll:
Nun, ich war felsenfest der Meinung, dass der C-Compiler hier einen
Upcast auf 32 Bit durchführt, BEVOR die Multiplikation und Left Shift
durchgeführt wird. Das war allerdings NICHT der Fall - so bekam ich für
startPage=128
dann
(( 256 * 128 ) << 1 ) = (32768 << 1 ) = 65536
*und wegen 16 Bit Überlauf (!!) dann 0* !
Ich muss ja gestehen, dass C nicht meine starke Seite ist (eher Java,
Python, Lisp), aber das hat mich dann doch umgehauen.
Geändert in
und ich bekomme 65536 für die startAddress.
Ist das ein Compiler-Fehler, oder tatsächlich meine C-Unwissenheit? Ich
dachte, hier würden automatisch Upcasts auf 32 Bit durchgeführt VOR der
Multiplikation / Left Shift Operation?
Mit der Bitte um Erleuchtung. Man lernt nie aus!
Vielen Dank, das Programm läuft jetzt!!
Zusammengefasst gab es also folgende Probleme:
- unterschiedliche 25LC1024 (second hand?); einige hatten Schutzbits
aktiviert
- Löschen der Schutzbits wurde nie ausgeführt (Prorammfehler)
- Test-Programm zeigte dann, dass die EEPROMs tatsächlich die richtige
Größe haben, 128 KBytes, und keine Fehler aufweisen
- dass Addressen über 65536 nicht korrekt addressiert werden konnte, lag
an fehlenden (uint32_t) casts, OBWOHL die address Zielvariable ja
32 Bit hatte (Compiler-Fehler?)
Michael W. schrieb:> (Compiler-Fehler?)
Da die Standardbegründung für ein nicht funktionierendes System
"gefakter Chinaschrott" nicht gezogen hat, kommt jetzt Plan B:
"Compilerfehler"
MfG Klaus
>> Nun, ich war felsenfest der Meinung, dass der C-Compiler hier einen> Upcast auf 32 Bit durchführt, BEVOR die Multiplikation und Left Shift> durchgeführt wird. Das war allerdings NICHT der Fall - so bekam ich für
Welcher Compiler war es denn?
Und welche Plattform?
Das define gibt dem Compiler ein int Literal,das er mit einem uint8_t
multiplizieren soll. Das Ergebnis ist wieder ein int. Erst am Ende aller
Berechnungen wird auf uint32_t ge'castet. Ist int nicht 32Bit (z.B.
AVR), dann fehlen immer die oberen 16 Bit (die bei int16_t -> uint32_t
ge'nullt werden)
Die Lösung scheinst du aber schon gefunden zu haben:
> startPage=128> dann> (( 256 * 128 ) << 1 ) = (32768 << 1 ) = 65536>> *und wegen 16 Bit Überlauf (!!) dann 0* !>> Ich muss ja gestehen, dass C nicht meine starke Seite ist (eher Java,> Python, Lisp), aber das hat mich dann doch umgehauen.
.
> Geändert in>>
>> und ich bekomme 65536 für die startAddress.>> Ist das ein Compiler-Fehler, oder tatsächlich meine C-Unwissenheit? Ich> dachte, hier würden automatisch Upcasts auf 32 Bit durchgeführt VOR der> Multiplikation / Left Shift Operation?
.
> Mit der Bitte um Erleuchtung. Man lernt nie aus!>> Vielen Dank, das Programm läuft jetzt!!>> Zusammengefasst gab es also folgende Probleme:> - unterschiedliche 25LC1024 (second hand?); einige hatten Schutzbits> aktiviert> - Löschen der Schutzbits wurde nie ausgeführt (Prorammfehler)> - Test-Programm zeigte dann, dass die EEPROMs tatsächlich die richtige> Größe haben, 128 KBytes, und keine Fehler aufweisen> - dass Addressen über 65536 nicht korrekt addressiert werden konnte, lag> an fehlenden (uint32_t) casts, OBWOHL die address Zielvariable ja> 32 Bit hatte (Compiler-Fehler?)
Michael W. schrieb:> Ist das ein Compiler-Fehler, oder tatsächlich meine C-Unwissenheit?
Deine C-Unwissenheit
Michael W. schrieb:> Ich> dachte, hier würden automatisch Upcasts auf 32 Bit durchgeführt VOR der> Multiplikation / Left Shift Operation?
Nö, das Beste kommt immer erst zum Schluss. Wenn man den Compiler nicht
zwingt rechnet er erst und castet dann, nicht umgedreht.
Carl D. schrieb:> Welcher Compiler war es denn?> Und welche Plattform?>> Das define gibt dem Compiler ein int Literal,das er mit einem uint8_t> multiplizieren soll. Das Ergebnis ist wieder ein int. Erst am Ende aller> Berechnungen wird auf uint32_t ge'castet. Ist int nicht 32Bit (z.B.> AVR), dann fehlen immer die oberen 16 Bit (die bei int16_t -> uint32_t> ge'nullt werden)
Ja, so scheint es zu sein... man lernt eben nie aus! Danke.
Ich verwende
WinAVR-20100110
Hoffe, das ist i.O. (oder werde ich dafür geschlachtet? :D)
Klaus schrieb:> Michael W. schrieb:>> (Compiler-Fehler?)>> Da die Standardbegründung für ein nicht funktionierendes System> "gefakter Chinaschrott" nicht gezogen hat, kommt jetzt Plan B:> "Compilerfehler">> MfG Klaus
Quatsch. Du musst schon den ganzen Text lesen, nicht nur Sound Bytes
"out of context" zitieren...
Außerdem funktioniert mein "System" jetzt ;-)
Michael W. schrieb:> Ist das ein Compiler-Fehler, oder tatsächlich meine C-Unwissenheit?
C-Unwissenheit.
Der Compiler berechnet immer erst die rechte Seite und nimmt dafür int
(16Bit), wenn nicht anders angegeben. Die Umwandlung ins Zielformat
erfolgt erst bei der Zuweisung.
Eine Fallgrube kann auch sein, wenn man int und unsigned int Operanden
hat. Dann wird im höheren Format, also unsigned int gerechnet. Soll das
Vorzeichen erhalten bleiben, muß man einen Operanden nach long casten.
Peter D. schrieb:> Michael W. schrieb:>> Ist das ein Compiler-Fehler, oder tatsächlich meine C-Unwissenheit?>> C-Unwissenheit.> Der Compiler berechnet immer erst die rechte Seite und nimmt dafür int> (16Bit), wenn nicht anders angegeben. Die Umwandlung ins Zielformat> erfolgt erst bei der Zuweisung.
Gut zu wissen! Wie gesagt, mein C ist schon ne Weile her (Mitte der
90er...)
Auf die Gefahr hin, noch mehr "Prügel" zu beziehen, aber hier seht ihr
jetzt woran ihr mitgeholfen habt ("mein Drahtverhau", wie er schon mal
so schön passend hier bezeichnet wurde):
https://youtu.be/k0D6YG4FTk4
Samples kommen aus dem SPI EEPROM, da der ATMega 644 natürlichh nicht
genug Platz dafür hat.