Servus,
habe über den BusPirate eine Verbindung zwischen PC und SPI-Flash
N25Q016 aufgebaut.
Darüber kann ich die Flash-internen Register lesen und schreiben und
auch ohne Probleme den Speicher löschen und auslesen.
Einziges Problem: sobald ich Daten hineinschreibe und anschließend den
beschriebenen Bereich wieder auslese, erhalte ich nur Datenmüll. Diesen
dafür reproduzierbar, d.h. schreiben->lesen ergibt das gleiche Output
wie schreiben->lesen->löschen->schreiben->lesen.
Das Ganze ist unabhängig davon, an welcher Stelle des Flash ich schreibe
und am Flashbaustein liegt's auch nicht, da das identische Verhalten bei
einem anderen gleichartigen IC auch auftritt.
Die SPI-Signale sehen sowohl von den Flanken als auch vom Timing her top
aus, daran sollte es also nicht liegen - die Spannungsversorgung ist
ebenfalls stabil.
Hat irgendeiner eine Idee, woran das liegen könnte? Muss ich irgendetwas
besonderes beim Schreiben beachten, damit das geht?
Gruß
Jorge
Jorge schrieb:> Hat irgendeiner eine Idee, woran das liegen könnte? Muss ich irgendetwas> besonderes beim Schreiben beachten, damit das geht?
Überprüfst du ob das schreiben der Page abgeschlossen ist, bevor du die
nächste Schreiboperation startest.
Sascha
Sascha W. schrieb:> Jorge schrieb:>> Hat irgendeiner eine Idee, woran das liegen könnte? Muss ich irgendetwas>> besonderes beim Schreiben beachten, damit das geht?>> Überprüfst du ob das schreiben der Page abgeschlossen ist, bevor du die> nächste Schreiboperation startest.>> Sascha
Ja, zuerst prüfe ich dass der Schreibvorgang beendet ist, dann lese ich
aus.
Siebzehn F. schrieb:> Ich wuerd auch mal das Datenblatt Zeile fuer Zeile durchgehen...
Das habe ich schon getan und weil ich dann mit meinem Latein am Ende
war, dachte ich mir, vielleicht hat hier ja jemand schon ähnliche
Erfahrungen gemacht und kann weiterhelfen.
Peter P. schrieb:> Vielleicht solltest du mal dein Programm/Script posten?
Das Skript sieht folgendermaßen aus:
> m 5 4 1 2 1 2 2> [0x06] [0xD8 0x00 0x00 0x00]> [0x06] [0x02 0x00 0x00 0x00 0x5A 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
0x0A 0x0B 0x0C 0x0D 0x0E 0x0F]
> [0x03 0x00 0x00 0x00 r:20]
Zur Erläuterung:
Die erste Zeile konfiguriert den BusPirate in den SPI-Modus zu wechsen.
Alle weiteren Zeilen sind direkt schon SPI-Befehle für den Flash, wobei
die öffnende eckige Klammer das Setzen des \CS-Signals bedeutet und
umgekehrt die schließende eckige Klammer das Deaktivieren des
\CS-Signals.
Zeile 2: Der Befehl 0x06 bedeutet das Write Enable-Bit im Flash zu
setzen um überhaupt irgendentwas schreiben zu können.
Anschließend wird mit dem Befehl 0xD8 der Sektor beginnend an der
Adresse 0x00 0x00 0x00 (alle Addressen im Flash sind als 24 Bit-Wert zu
übergeben) gelöscht.
Zeile 3: 0x06 = Write Enable Bit setzen; 0x02 = Page Programm beginnend
mit Adresse 0x000000, schreibe die 17 angegebenen Werte 0x5A bis 0x0F
Zeile 4: Befehl 0x03 bedeutet Read Memory, gefolgt von der Startadresse
0x000000 sowie 20 gesendeten Dummy Bytes, die dann gleichzeitig 20 Bytes
empfangen/einlesen.
=> Im Ergebnis stimmen die zurückgelesenen 20 Bytes nicht mit den
gesendeten 17 Bytes überein sondern es wird irgendetwas anderes
geschrieben als beim Page Program übertragen.
Interessanterweise ist aber zumindest irgendetwas an diesen
Speicherbereich geschrieben worden - wenn auch nur Datenmüll - daher
muss der Schreibbefehl grundsätzlich passen.
Wenn ich den Lesebefehl 0x03 direkt nach dem Page Erase ausführe, sehe
ich dass an dem Bereich tatsächlich alle Bytes auf 0xFF zurückgesetzt
wurden.
Für mich ist somit unlogisch, weshalb alle Befehle und Adressen korrekt
gesendet werden, die zu schreibenden Datenbytes jedoch nicht geschrieben
sondern durch irgendetwas anderes ersetzt werden.
Jorge schrieb:> Die erste Zeile konfiguriert den BusPirate in den SPI-Modus zu wechsen.
In welchen SPI Modus? Kannst du das ID Register korrekt auslesen?
Jorge schrieb:> Für mich ist somit unlogisch, weshalb alle Befehle und Adressen korrekt> gesendet werden, die zu schreibenden Datenbytes jedoch nicht geschrieben> sondern durch irgendetwas anderes ersetzt werden.
das weißt du nicht. es könnte sein daß du die daten nicht sauber gelesen
bekommst und nur 0xFF als sonderfall funktioniert. Lothars tipp mit der
ID ist da glaube ich gar nicht schlecht.
Lothar M. schrieb:> Jorge schrieb:>> Die erste Zeile konfiguriert den BusPirate in den SPI-Modus zu wechsen.> In welchen SPI Modus? Kannst du das ID Register korrekt auslesen?
Der SPI-Modus wie beschrieben bedeutet:
m 5 = Mode 5 = SPI-Modus
4 = 1MHz Taktrate
1 = Clock Polarity: Idle Low
2 = Output Clock Edge: Active to Idle
1 = Input Sample Phase: Middle
2 = CS: inverted (\CS)
2 = Output Type: Push-Pull
Ok, ich gebe zu dass das gepostete Skript nur den eigentlichen
Schreibvorgang wiedergibt.
Natürlich habe ich zu Beginn ganz einfache Sache wie ID-Register
auslesen (Befehl 0x9E) und nach dem Schreiben sowie immer mal
zwischendurch auch Status- / Flagregister auslesen (Befehle 0x05 / 0x70)
ausgeführt um zu schauen ob der Schreib-/Löschvorgang beendet ist bzw.
eine Fehlermeldung hervorgerufen hat (Fehlerbit im Flagregister
gesetzt).
Rückmeldung beim Statusregister ist immer 0x00 und Flagregister 0x80,
d.h. nicht mehr "busy", keine Fehler beim Löschen oder Schreiben.
Daher wundert es mich ja so sehr, dass das Registerauslesen klappt, das
Speicherbeschreiben aber nicht.
Das Verhalten ist übrigens identisch, egal ob ich beim BusPirate als
Taktrate 30kHz, 125kHz, 250kHz oder 1MHz einstelle und auch ob ich
tatsächlich auf Adresse 0x000000 anfange zu schreiben oder ein paar
Pages "weiter hinten".
Kurzes Update:
Möglicherweise ist es ein reines "Leseproblem". In der Zwischenzeit habe
ich herausgefunden, dass wenn ich das ID-Register auslese, auch dort nur
seltsamer "Datenmüll" herauskommt, der aber bei jedem Auslesen gleich
(falsch) bleibt.
Laut Datenblatt weiß ich aber, welche Bytes tatsächlich drin stehen.
Also habe ich die korrekte Bytefolge direkt mal an den Anfang des
Flash-Speichers einprogrammiert und wieder ausgelesen.
Und siehe da, die wiederausgelesene Bytefolge ist identisch (falsch) mit
der, die ich erhalte wenn ich das ID-Register auslese.
Daher vermute ich, dass irgendetwas im Flash-internen Controller
schiefläuft, wenn ich mit dem Bus Pirate einen Lesebefehl ausführe.
Nächster Vergleich ist jetzt, zu schauen, was passiert, wenn ich den
Flash per "echtem" Programmer bespiele/auslese. Wenn dort alles ok ist,
hängt es wohl eher am Bus Pirate bzw. dessen "langen" Zeitdauern
zwischen zwei einzelnen übertragenen SPI-Bytes als am Flash selber.
Schade, dass ich meinen Bus Pirate (Version 4 mit Firmware 6.1) nicht in
den Raw Byte Modus versetzen kann, doch das ist wieder eine andere
Geschichte...
Wenn du ein Oszi hast, probiert doch einmal damit den Daten mitzulesen
und mit denen, die dir der Pirate ausgibt zu vergleichen.
Und hast mal einem Link zu dem dem Datenblatt des Flashs?
Mit ziemlicher Sicherheit ist es nicht der Flash, wenn nicht mal ID
lesen klappt. Sind die Bits verschoben? Dann wirds der SPI Mode sein.
Die Geschwindigkeit spielt keine Rolle. Ist ja das schöne an SPI. Wir
setzen die größeren Chips aus der Reihe ein, da gibts keine Probleme.
Ich sehe in deinem Code nicht, dass du nach dem Löschen und nach dem
Schreiben wartest, bis das Flash fertig ist.
Hierfür busy-polled man üblicherweise das Status Register (CMD = 0x05)
und guckt sich bit 0 an.
Solange dieses Bit gesetzt ist, musst du warten.
Alternativ kannst du zwischen Löschen und Schreiben und Schreiben und
Lesen einfach mal eine Pause von 1 Sekunde machen.
Ausserdem besitzen die meisten Flashes Protection bits, die evtl. noch
gesetzt sind.
Und natürlich den externen WP_N Pin.
Hast Du einen Abblockkondensator am Flash? Sonst kannst Du
Spannungseinbrüche haben. Sieht mir aber eher so aus, als ob Du auf die
falsche Flanke samplest. SPI hat diesbezüglich vier Modi. Die kann man
im Zweifelsfall einfach mal durchprobieren und dann in den Datenblättern
nachschauen welcher der wirklich richtige ist.
Da fällt mir noch was ein. Jedenfalls der N25Q256 will nach dem Power On
auf jeden Fall einen Reset, entweder über den Pin oder über das Software
Reset Kommando. Sonst macht der nix gesxheites. Steht leider nicht om
Datenblatt.
Das dürfte dann der Grund sein. Hoffentlich ließt der OP noch mit.
Jedenfalls ist das auch für mich gut zu wissen, da ich demnächst auch
mal so ein Teil brauchen werde.
Jorge schrieb:> erhalte ich nur Datenmüll.
Dann würde ich den "Müll" mal analysieren und erstmal auswertbare
Pattern schreiben (0xFF, 0x00, 0x01, 0x02, 0x04 usw.)
Hi zusammen,
und danke für's Ideen einwerfen!
Das Datenblatt zum Flash findet sich auf der Micron-Seite unter
http://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/n25q/n25q_16mb_1_8v_65nm.pdf
Um die Recherche etwas zu vereinfachen, betrachten wir erst einmal nur
das Auslesen des ID-Registers. Dazu anbei mal ein paar Oszillogramme,
Bild 1 ist die Übersicht, Bild 2 ein Zoom in den Teil wo der Lesebefehl
0x9E gesendet wird und Bild 3 ein Zoom in den Teil wo der Flash
antwortet.
Gelb = \CS
Blau = CLK
Violett = MOSI
Grün = MISO
Mike R. schrieb:> Wenn du ein Oszi hast, probiert doch einmal damit den Daten> mitzulesen> und mit denen, die dir der Pirate ausgibt zu vergleichen.>> Und hast mal einem Link zu dem dem Datenblatt des Flashs?
Am Oszilloskop stimmt alles exakt mit dem überein, was ich über den Bus
Pirate ausgeben lasse. Datenblatt siehe Link oben.
Lothar M. schrieb:> Jorge schrieb:>> Kurzes Update:>> Möglicherweise ist es ein reines "Leseproblem".> Evtl. interpretiert da einer den SPI Mode falsch...
Ich habe nun verschiedene Dinge am BusPirate ausprobiert: Ändern nur der
Clock Polarität oder nur der Output Clock Edge funktioniert gar nicht.
Beides gleichzeitig geändert geht wiederum genauso wie der Default-Mode.
Das entspricht auch den zwei Modi, die laut Datenblatt vom Flash
unterstützt werden (CPO = 0 und CPH = 0 sowie CPO = 1 und CPH = 1).
An welcher Stelle könnte ich da noch etwas fehlinterpretieren?
Christian R. schrieb:> Mit ziemlicher Sicherheit ist es nicht der Flash, wenn nicht mal> ID> lesen klappt. Sind die Bits verschoben? Dann wirds der SPI Mode sein.> Die Geschwindigkeit spielt keine Rolle. Ist ja das schöne an SPI. Wir> setzen die größeren Chips aus der Reihe ein, da gibts keine Probleme.
Verschobene Bits habe ich auch vermutet, aber bei Betrachtung der
Oszillogramme ist es egal wie man es schieben oder invertieren möchte,
die zurückgelesenen Daten stimmen nicht mit dem eigentlichen Inhalt des
ID-Registers überein.
Da andererseits aber das gleiche Ergebnis zurückgeliefert wird, egal ob
ich das ID-Register direkt auslese oder ob ich den laut Datenblatt im
ID-Register stehenden Inhalt zuerst in den Flash hineinschreibe und dann
dort wieder auslese, vermute ich, dass es doch irgendein Timing
innerhalb des Flash-Chips ist.
Joe F. schrieb:> Ich sehe in deinem Code nicht, dass du nach dem Löschen und nach> dem> Schreiben wartest, bis das Flash fertig ist.> Hierfür busy-polled man üblicherweise das Status Register (CMD = 0x05)> und guckt sich bit 0 an.> Solange dieses Bit gesetzt ist, musst du warten.> Alternativ kannst du zwischen Löschen und Schreiben und Schreiben und> Lesen einfach mal eine Pause von 1 Sekunde machen.>> Ausserdem besitzen die meisten Flashes Protection bits, die evtl. noch> gesetzt sind.>> Und natürlich den externen WP_N Pin.
Protection Bits und externer WP- und Hold-Pin sind deaktivert, also kein
Schreibschutz aktiv. Die Warteroutine habe ich im Skript der Einfachheit
halber weggelassen, implementiert ist sie aber (auch wenn schon beim
ersten Auslesen des Statusregisters eine Null zurückkommt da der
BusPirate zwischen einzelnen Bytes doch ausreichend Zeit lässt).
Aber wie schon angesprochen, wenn man mal das Schreiben außen vor lässt
und nur den Lesevorgang des ID-Registers betrachtet, gibt es schon
merkwürdige Schwierigkeiten.
Thomas R. schrieb:> Hast Du einen Abblockkondensator am Flash? Sonst kannst Du> Spannungseinbrüche haben. Sieht mir aber eher so aus, als ob Du auf die> falsche Flanke samplest. SPI hat diesbezüglich vier Modi. Die kann man> im Zweifelsfall einfach mal durchprobieren und dann in den Datenblättern> nachschauen welcher der wirklich richtige ist.
Selbstverständlich, der Chip ist in direkter Nähe entkoppelt, die
gesamte Platine noch mit einem Elko und die Versorgung selbst zunächst
ein Labornetzteil.
Sampeln auf der falschen Flanke ist wie in den Oszillogrammen zu sehen
leider nicht der Fall. Modis wie etwas weiter oben beschrieben sind
schon alle durchprobiert.
Christian R. schrieb:> Da fällt mir noch was ein. Jedenfalls der N25Q256 will nach dem> Power On> auf jeden Fall einen Reset, entweder über den Pin oder über das Software> Reset Kommando. Sonst macht der nix gesxheites. Steht leider nicht om> Datenblatt.
Sehr gute Idee! Habe den Reset mal mit eingebaut (Kommando 0x66, warten,
0x99) - leider aber ohne Erfolg. Sowohl vor als auch nach dem Reset ist
die Antwort beim ID-Registerauslesen identisch.
Peter D. schrieb:> Jorge schrieb:>> erhalte ich nur Datenmüll.>> Dann würde ich den "Müll" mal analysieren und erstmal auswertbare> Pattern schreiben (0xFF, 0x00, 0x01, 0x02, 0x04 usw.)
So bin ich auch vorgegangen. Das Ergebnis sieht folgendermaßen aus:
Schreiben: 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A
Lesen: 0x00 0x00 0x08 0x00 0x01 0x03 0x00 0x00 0x1F 0xFF 0xFF...
Wie schon beschrieben - mit verschobenen Bits oder falschem SPI-Modus
ist das nicht wirklich zu erklären. Daher erhoffe ich mir Besserung,
wenn ein "echter" Programmer dranhängt.
Du hast ein elektrisches Problem. Deshalb siehst Du den Takt auf der
MOSI. Ich glaube aber nicht, daß das der Root-Cause ist. Schicke mal das
Kommando vergrößert. Ich möchte mal sehen, was ich da raus lesen würde.
BTW, bist Du im richtigen SPI Mode? Mansche Controller erlauben das
Umstellen von Big- auf Little-Endian (LSB First).
So, in der Zwischenzeit hat sich das Problem nun endlich gelöst:
Asche auf mein Haupt - es lag maßgeblich am fliegend verdrahteten
Aufbau: Drähte vom BusPirate zur Lochrasterplatine,
Spannungsteilerwiderstände 8kOhm über 10kOhm um von 3.3V auf 1.8V zu
kommen und anschließend ein paar Drähte zur eigentlichen Platine mit dem
Flash drauf.
Wenn man an der falschen Stelle misst, sehen die Signale gut aus ;)
Erklärt zwar nicht, weshalb die Kommandodaten korrekt im Flash ankamen
und die ausgelesenen Daten wiederholbar exakt falsch waren, aber muss
damit zusammenhängen.
Jetzt ist der Signalpfad zwischen BusPirate und Flash deutlich kürzer
und die Widerstandsverhältnisse auf 0.82kOhm und 1kOhm reduziert um mehr
Strom treiben zu können.
=> Die Kommunikation läuft jetzt stabil, alle ausgelesenen Register
bringen die richtigen Daten und auch das Schreiben und Wiederauslesen
des Flashs funktioniert einwandfrei. Der IC selbst ist also entgegen
meiner ersten Annahme fehlerfrei.
Zweite Erkenntnis: Der BusPirate hat noch mindestens einen Bug. Wenn ich
mehr als 32 Datenbytes auf einmal vom BusPirate zum Flash übertragen
lassen möchte, dann verschluckt der BP gerne mal ein paar Bytes oder er
verfälscht einige wenige. Um das herauszufinden musste ich ganz schön
lange auf dem Oszilloskop herumscrollen und dekodieren, da ja der
Anfang, also mindestens 32 Bytes jeder SPI-Kommunikation korrekt
abläuft.
Schöner Mist wenn man den BusPirate doch eigentlich nutzt weil man davon
ausgeht dass wenigstens das Tool korrekt arbeitet...
Danke an alle fürs Miträtseln!
> Wenn man an der falschen Stelle misst, sehen die Signale gut aus ;)
In der ELO gab es damals einen Artikel mit dem Namen "Wer mißt mißt
Mist".
Da ich schon viele Root-Cause-Analysen gemacht habe möchte ich das
Phänomen allen interessierten erklären:
Wenn Du mit einem 1.8V Ausgang einen 3.3V Eingang treibst bist Du, falls
überhaupt, nur knapp über dem Thrshold des 3.3V Eingangs. Da reichen Dir
ein paar mV Ground-Shift um die Übertragung kaputt zu machen. Das geht
so auf keinen Fall. Wir sehen (schreiben) uns dann wieder bei
Temperaturänderung.
Wenn es Dir nicht auf minimalsten Stromverbrauch ankommt, kannst Du den
1.8V->3.3V Wandler auch mit Widerständen machen. Z.B. auch wieder 1kOhm
am Ausgang (MISO) und bei ca. 0.6V low Pegel 4.7kOhm gegen 3.3V. Dann
hast Du einen High Pegel von ca. 2V. Dabei wird Dir im deselektierten
Zustand ein kleiner Strom durch die Schutzdiode des FLASH-Ausgangs
fließen und diesen auf ca. 2.3V hoch ziehen. Das ist nicht kritisch, da
dieser die zerstörerichen (meist 50) mA nicht erreicht.
Besser, bzw. notwendig falls es auf geringe Stromaufnahme ankommt, ist
ein Pegelwandler.
Und hier noch ein paar "k" "k" "k" falls noch welche fehlen. Meine
Tastatur hat wohl ein Problem. :-)
Thomas R. schrieb:>> Wenn man an der falschen Stelle misst, sehen die Signale gut aus> ;)>> In der ELO gab es damals einen Artikel mit dem Namen "Wer mißt mißt> Mist".>> Da ich schon viele Root-Cause-Analysen gemacht habe möchte ich das> Phänomen allen interessierten erklären:>> Wenn Du mit einem 1.8V Ausgang einen 3.3V Eingang treibst bist Du, falls> überhaupt, nur knapp über dem Thrshold des 3.3V Eingangs. Da reichen Dir> ein paar mV Ground-Shift um die Übertragung kaputt zu machen. Das geht> so auf keinen Fall. Wir sehen (schreiben) uns dann wieder bei> Temperaturänderung.>> Wenn es Dir nicht auf minimalsten Stromverbrauch ankommt, kannst Du den> 1.8V->3.3V Wandler auch mit Widerständen machen. Z.B. auch wieder 1kOhm> am Ausgang (MISO) und bei ca. 0.6V low Pegel 4.7kOhm gegen 3.3V. Dann> hast Du einen High Pegel von ca. 2V. Dabei wird Dir im deselektierten> Zustand ein kleiner Strom durch die Schutzdiode des FLASH-Ausgangs> fließen und diesen auf ca. 2.3V hoch ziehen. Das ist nicht kritisch, da> dieser die zerstörerichen (meist 50) mA nicht erreicht.>> Besser, bzw. notwendig falls es auf geringe Stromaufnahme ankommt, ist> ein Pegelwandler.>> Und hier noch ein paar "k" "k" "k" falls noch welche fehlen. Meine> Tastatur hat wohl ein Problem. :-)
Dem möchte ich widersprechen - der "verbotene" Pegel des MISO-Rückkanals
war in der fliegenden Verdrahtung genau NICHT das Problem.
Dort habe ich ja in "BusPirate-Nähe" das Signal oszillographiert und die
Bit-Daten waren exakt so, wie es der BusPirate auch mitgeloggt hat,
sprich der BusPirate selbst hat einen 1.8V-Pegel sauber als HIGH
erkannt.
Wie in den Oszillogrammen zu sehen, waren schon die vom Flash kommenden
Daten als Bitmuster "falsch".
Der Fehler muss also eher mit einem verschliffenen oder "verspiketen"
Clock-Signal zusammenhängen, das einen negativen Einfluss auf die
Flash-internen Timings hatte.
Jorge schrieb:> Spannungsteilerwiderstände 8kOhm über 10kOhm um von 3.3V auf 1.8V zu> kommen
Das ist natürlich arg hochohmig, für steile Flanken nicht geeignet.
390R + 470R wären besser und dann auch direkt am Eingangspin plazieren.
Peter D. schrieb:> Jorge schrieb:>> Spannungsteilerwiderstände 8kOhm über 10kOhm um von 3.3V auf 1.8V zu>> kommen>> Das ist natürlich arg hochohmig, für steile Flanken nicht geeignet.> 390R + 470R wären besser und dann auch direkt am Eingangspin plazieren.
Ja, jetzt habe ich das auch auf die harte Tour gelernt :)
Jorge schrieb:> Ja, jetzt habe ich das auch auf die harte Tour gelernt :)
Du hättest solche wichtigen Schaltungsdetails einfach schon im ersten
Post nennen müssen, dann wäre der Fehler schnell aufgefallen.