Wie schreibe ich in den SPI-Flash-Speicher?

8

Ich arbeite an einer Audioanwendung, bei der ich Audiodaten nicht auf einer SD-Karte ( Waveshield on Arduino), sondern auf einem SPI-Flash-Speicher-IC speichere und mein eigenes Board mit MCU, DAC und Verstärker rolle.

Ich benutze einen Winbond W25Q80BVSSIG .

Ich bin ziemlich vertraut mit der Programmierung von AVR mit dem AVRISP mkII oder dem USBTiny. Wird das Schreiben von Daten zum Flashen mit demselben Programmierer durchgeführt? Ich konnte bei der Suche nach SPI-Flash-Speicherprogrammierern nichts finden.

Diese Frage ist ein Follow up diesem ein .

JYelton
quelle
Ich weiß nicht, ob es einen Programmierer gibt, der dies speziell für Sie problemlos von einem PC oder Ähnlichem aus erledigen kann. Wenn jedoch eine CPLD in Ihrer Schaltung enthalten ist, können Sie diese so konfigurieren, dass Daten in den Flash-Speicher geschrieben werden.
deed02392
Ich denke, SPI-Flash-Module sind heutzutage so konzipiert, dass sie Firmware / BIOS speichern, die die CPU in den meisten PCs verwendet. Nicht für robuste Speichergeräte.
Marschall Handwerk

Antworten:

12

Wenn Sie einfach nach einer Möglichkeit suchen, den Winbond SPI-Flash mit "vorinstallierten" Daten zu programmieren, die Ihr Mikrocontroller zur Verwendung während der Ausführung lesen würde, sollten Sie sich einen Programmierer ansehen, der In-Circuit-Programmierung durchführen kann des SPI Flash Chips. Dies wird auch als In-System-Programming (ISP) bezeichnet.

Eine Wahl ist der Programmierer von DediProg. Dieses über USB angeschlossene Gerät kann im Schaltkreis programmieren, wenn Sie Ihre Karte richtig gestalten. Sie verkaufen sogar einen Adapterclip, der in das SOW-16-Paket eingebaut werden kann, ohne dass ein separater Programmierheader auf Ihrer Platine erstellt werden muss. DediProg verfügt über Bulletins mit Anwendungsinformationen, die beim korrekten Design für den Einsatz in Schaltkreisen helfen. Die Hauptstrategie für das Design besteht darin, einen einfachen Weg zu finden, um die SPI-Schnittstellentreiber in Ihrem MCU-System so zu isolieren, dass sie die Treiber im SPI-Programmier-Pod nicht stören. Der einfachste Weg, dies zu tun, besteht darin, Vorwiderstände in die MCU-gesteuerten Leitungen zwischen der MCU und dem SPI-Blitz einzubauen. Der Programmierer würde auf der SPI-Flash-Seite der Vorwiderstände anschließen. Alternative Methoden könnten das Hinzufügen eines MUX oder analoger Schalter in den angesteuerten Schnittstellenleitungen umfassen. Ein noch klügeres Schema ist das Hinzufügen eines "

Geben Sie hier die Bildbeschreibung ein

Eine zweite Option , die ebenfalls in Betracht gezogen werden sollte, ist der USB-Programmierer von ASIX . Der Presto kann verschiedene Arten von SPI- und I 2 C-Geräten ausführen, einschließlich SPI-Flash-Geräten. Ich habe eines dieser Geräte speziell für die Programmierung von Atmel-MCUs und verschiedenen Arten von SPI-Flash-Geräten. Es ist eine kostengünstigere Lösung als das oben genannte Gerät, aber nicht ganz so flexibel. Ihr teureres Gerät namens Forte kann mehr, weil es mehr Zielschnittstellen-Pins hat.

Geben Sie hier die Bildbeschreibung ein

Manchmal kann es vorteilhaft sein, einen Programmierer an eine Zielplatine anschließen zu können, ohne einen Programmierheader hinzufügen zu müssen. Eine gute Lösung hierfür besteht darin, einen kleinen Satz Pads in einem speziellen Footprint zu platzieren, der von einer Firma namens TagConnect definiert wurde . Sie produzieren und verkaufen eine Reihe von Schnellkupplungs-Programmierkabeln mit Pogo-Pins, die den besonderen Platzbedarf auf der Platine berücksichtigen. Es gibt 6-polige, 10-polige und 14-polige Versionen des Kabels für eine Reihe von Anwendungen. Die Kosten für die Kabel sind sehr vernünftig.

Geben Sie hier die Bildbeschreibung ein

Michael Karas
quelle
Das ist sehr hilfreich. Ich plane, den Flash-Speicher zu programmieren, bevor ich ihn auf die endgültige Platine löte. Bisher habe ich das für MCUs gemacht und es hat gut funktioniert. Ich bin mir nicht sicher, ob die Bereitstellung von ISP-Pins auf der Leiterplatte eine gute Idee ist oder nicht, da sie nach Abschluss nicht neu programmiert werden sollen.
JYelton
1
@JYelton - Nach meiner Erfahrung ist es aus mehreren Gründen eine gute Idee, für ISP zu planen. ECOs (Engineering Change Orders) sind eine Tatsache im Produktzyklus. Jemand oder etwas wird eine Änderung des Flash-Inhalts verlangen, sobald Sie mit der Produktion beginnen. Flash-Chips sind manchmal anfällig für unerwartete Rauschstörungen in der Schaltung und haben letztendlich eine Beeinträchtigung ihres Inhalts. Ein weiterer Grund für ISP.
Michael Karas
1
Gibt es einen "Standard" -Header, der mit den meisten dieser Programmierer zumindest über mitgelieferte Adapterkabel kompatibel ist? Ich habe 2x4- und 2x5-Pin-Header mit verschiedenen Pinbelegungen gesehen. Siehe auch flashrom.org/Supported_hardware
kert
Jeder hat seine eigene Vorstellung von vernünftig. Die Tag-Connect-Kabel kosten zwischen 35 und 40 US-Dollar.
Markrages
1
@markrages - Für ein bestimmtes Entwicklungslabor oder eine werkseitige Programmierstation müssen Sie jedoch nur ein Kabel erwerben. Sie benötigen nicht für jedes Produkt eine. Außerdem sind diese Kabel viel billiger als der Versuch, Ihre eigene Pogo-Pin-Befestigung zu rollen, um ISP ohne Stecker zu ermöglichen.
Michael Karas
8

Ich wette, Sie könnten es mit einem Buspiraten tun, ohne Ihre MCU zu durchlaufen ... mit der Sie etwas willkürliche serielle Interaktionen direkt auf einem Chip mithilfe von SPI-, I2C- oder UART-Kommunikation durchführen können. Es könnte ein wenig Arbeit erfordern, es zu "skripten", aber es würde Sie wahrscheinlich die Arbeit machen lassen.

Ich habe auch spezielle Tools zum direkten Laden von EEPROMs über I2C gesehen, aber nicht Flash und nicht SPI speziell.

vicatcu
quelle
Ich frage mich, ob meine Auswahl an SPI-Flash gut ist, wenn man bedenkt, wie (anscheinend) undurchsichtig die Methoden sind, um auf die gesprengten Dinge zu schreiben.
JYelton
1
Das würde einige ernsthafte Skripte erfordern, aber trotzdem eine gute Idee. Für meinen Geschmack etwas zu kompliziert. Vielleicht sollten Sie eine SD-Karte in Betracht ziehen? Dann müssen Sie sich nur noch um das Lesen kümmern und mit einem Computer darauf
schreiben
Der aktuelle Prototyp verwendet einen Arduino und Waveshield (mit SD-Kartenleser). Ich möchte von der SD-Karte wegkommen, weil ich glaube, dass die Kosten geringer sind (kein Lesegerät und keine Karte) und auch manipulationssicherer.
JYelton
7

Ich habe noch nie von anderen Tools gehört, die SPI direkt mit einem solchen Chip kommunizieren, und ich denke, dass dies unmöglich ist, da "alle" Chips unterschiedliche Aufrufe für unterschiedliche Operationen erfordern.

Der Chip benötigt SPI-Aufrufe zum Schreiben, Lesen, Ändern des Sektors, der Datengröße usw. Im Kapitel 7.2 Anweisungen im Datenblatt finden Sie alle SPI-Befehle, die Sie an ihn senden können. Da nicht alle externen Flash-Speicher denselben Befehlssatz haben, müssen Sie eine angepasste Anwendung für diesen schreiben.

EDIT: Als Follow-up würde ich wirklich einen von Atmels eigenen SPI-Flash-Speichern empfehlen, da die meisten von ihnen bereits offenen verfügbaren Code für sie geschrieben haben. Wenn Sie sich diesen Beitrag von AVRFreaks ansehen , erhalten Sie Code für einige der seriellen Atmels AT45xxxx-Flash-Chips.

chwi
quelle
Wenn ich Sie richtig verstehe, sollte ich ein Programm für meine MCU schreiben, das dann die Daten in den Flash-Speicher schreibt? Das Problem ist, dass die MCU weniger Speicher hat als der externe Flash, daher bin ich etwas ratlos.
JYelton
Ja. Sie können mit UART Daten von der seriellen Leitung Ihres Computers senden, die Sie in den Flash schreiben. Sie können auch mehrere Programme für die MCU schreiben und den Flash einige Blöcke gleichzeitig programmieren. Es mag etwas zeitaufwändig sein, aber es funktioniert, da der externe Blitz nicht gelöscht wird, solange Sie die sich ändernden Sektoren korrekt
verfolgen
2
Dies ist die richtige Antwort. Sie benötigen also ein Programm auf Ihrem PC, um Chunks auf die MCU herunterzuladen, die sie dann in Flash schreiben. Es ist hilfreich, wenn eine Fehlerprüfung durchgeführt wird und Sie kein neues Programm auf den PC schreiben müssen. Daher schlage ich vor, dass Sie Code für XMODEM oder ähnliches finden.
pjc50
@ pjc50 ... nicht so schnell bei der Erklärung der 'richtigen Antwort' :)
vicatcu
Tatsächlich können viele Programmierer Flash-Speicher programmieren. und eines der gängigen Programmierschemata, die mit den atmel-Mikros verwendet werden, kommt SPI zunächst ziemlich nahe.
Chris Stratton
4

Ich habe einen " FlashCAT " -Programmierer von Embedded Computers für etwa 30 US-Dollar gekauft. Es war überraschend einfach, über USB eine Verbindung zum PC herzustellen und Dateien in den Winbond-Flash-Speicher zu schreiben. Die Methoden und Programmierer in anderen Antworten sind wahrscheinlich genauso gut, einige teurer oder DIY, aber dies ist eine billige und einfache Methode, die zu dem passt, was ich gesucht habe.

Hier ist ein Bild des Setups:

Programmieren mit FlashCAT

Der FlashCAT-Programmierer ist links mit USB verbunden. Es wird die SPI-Programmier-Firmware (im Gegensatz zu JTAG) ausgeführt und der Flash-Speicher mit Strom versorgt. Die zugeführte Stromversorgung kann mit einem Jumper ausgewählt werden (3,3 V oder 5 V).

Ich habe eine SOIC-zu-DIP-Buchse auf dem Steckbrett, um das Programmieren mehrerer Chips zu vereinfachen. (Sie können auch einen anderen Flash-Speicher-IC auf dem Steckbrett sehen.)

FlashCAT-Software

Ich habe meine Audiodatei noch nicht in das richtige Binärformat konvertiert, aber ich habe eine 211 KB WAV-Datei in den Speicher geschrieben, um sie zu testen (siehe Abbildung oben). Ich habe es dann zurückgelesen und als neue Datei gespeichert, in .wav umbenannt und es wird korrekt auf dem PC abgespielt.

Der nächste Schritt besteht darin, die Datei ordnungsgemäß zu codieren und die AVR-Software zu schreiben, um die Daten zu lesen und über einen DAC zu senden.

Haftungsausschluss: Ich bin nicht mit Embedded Computers verbunden. Ich bin nur ein Kunde, der etwas Günstiges ausgewählt hat und Informationen über die Erfahrungen mit dem Produkt austauscht.

JYelton
quelle
4

Etwas spät zur Diskussion, aber für alle, die es nach einer Suche lesen ...

Eine Sache, die ich nicht erwähnt habe und die beim Programmieren von SPI-Flash-Chips absolut kritisch ist, ist die Steuerung des Chip Select (CS_) -Pins. Der Chip Select-Pin wird verwendet, um Befehle an den SPI-Flash zu setzen. Insbesondere muss ein Übergang von CS_hoch zu CS_niedrig unmittelbar vor der Ausgabe eines Schreiboperations-Operationscodes (WREN, BE, SE, PP) erfolgen. Wenn zwischen dem CS_-Übergang (dh nachdem CS_ niedrig geworden ist) und vor der Übertragung des Schreiboperationscodes eine Aktivität besteht, wird der Schreiboperationscode normalerweise ignoriert.

Was in SPI-Flash-Datenblättern nicht häufig erklärt wird, da es ein fester Bestandteil des SPI-Protokolls ist, was ebenfalls kritisch ist, ist, dass man für jedes Byte, das man auf dem SPI-Bus sendet, ein Byte zurückerhält. Außerdem kann man keine Bytes empfangen, es sei denn, man sendet ein Byte.

Typischerweise hat der SPI-Master, den der Benutzer befiehlt, einen Sendepuffer, der Bytes auf der MOSI-Leitung des SPI-Busses sendet, und einen Empfangspuffer, der Bytes von der MISO-Leitung des SPI-Busses empfängt.

Damit Daten im Empfangspuffer angezeigt werden, müssen einige Daten aus dem Sendepuffer gesendet worden sein. In ähnlicher Weise werden jedes Mal, wenn Daten aus dem Sendepuffer gesendet werden, Daten im Empfangspuffer angezeigt.

Wenn man beim Ausgleich von Sende- und Empfangslesungen nicht aufpasst, weiß man nicht, was im Empfangspuffer zu erwarten ist. Wenn der Empfangspuffer überläuft, werden Daten normalerweise nur verschüttet und gehen verloren.

Wenn man also einen Lesebefehl sendet, der aus einem Ein-Byte-Op-Code und drei Adressbytes besteht, empfängt man zuerst vier Bytes "Müll" im SPI-Master-Empfangspuffer. Diese vier Müllbytes entsprechen dem Operationscode und drei Adressbytes. Während diese übertragen werden, weiß der Flash noch nicht, was er lesen soll, und gibt nur vier Müllwörter zurück.

Nachdem diese vier Müllwörter zurückgegeben wurden, müssen Sie eine Datenmenge senden, die der Menge entspricht, die Sie lesen möchten, um etwas anderes im Empfangspuffer zu erhalten. Nach dem Operationscode und der Adresse spielt es keine Rolle, was Sie senden, es ist nur ein Füllstoff, um die Read DAta vom SPI-Flash zum Empfangspuffer zu verschieben.

Wenn Sie die ersten vier zurückgegebenen Müllwörter nicht sorgfältig nachverfolgt haben, denken Sie möglicherweise, dass eines oder mehrere davon Teil Ihrer zurückgegebenen Lesedaten sind.

Um zu wissen, was Sie tatsächlich aus dem Empfangspuffer erhalten, ist es wichtig, die Größe Ihres Puffers zu kennen, zu wissen, ob er leer oder voll ist (normalerweise gibt es ein Registerstatusbit, um dies zu melden) und zu verfolgen, wie viel Zeug, das Sie gesendet haben und wie viel Sie erhalten haben.

Bevor Sie einen SPI-Flash-Vorgang starten, sollten Sie den Empfangs-FIFO "entleeren". Dies bedeutet, dass Sie den Status des Empfangspuffers überprüfen und leeren müssen (normalerweise durch Lesen des Empfangspuffers), falls dieser noch nicht leer ist. Normalerweise schadet das Entleeren (Lesen) eines bereits leeren Empfangspuffers nicht.

Die folgenden Informationen sind aus den Zeitdiagrammen in den Datenblättern von SPI-Flashs verfügbar, aber manchmal übersehen die Leute Bits. Alle Befehle und Daten werden über den SPI-Bus an den SPI-Flash ausgegeben. Die Reihenfolge zum Lesen eines SPI-Flashs lautet:

1) Start with CS_ high.
2) Bring CS_ low.
3) Issue "Read" op code to SPI Flash.
4) Issue three address bytes to SPI Flash.
5) "Receive" four garbage words in Receive Buffer.
6) Transmit as many arbitrary bytes (don't cares) as you wish to receive. 
Number of transmitted bytes after address equals size of desired read.
7) Receive read data in the Receive Buffer.
8) When you've read the desired amount of data, set CS_ high to end the Read command.
If you skip this step, any additional transmissions will be interpreted as 
request for more data from (a continuation of) this Read.

Beachten Sie, dass die Schritte 6 und 7 abhängig von der Größe des Lesevorgangs und der Größe Ihrer Empfangs- und Sendepuffer verschachtelt und wiederholt werden müssen. Wenn Sie eine größere Anzahl von Wörtern auf einmal senden, als Ihr Empfangspuffer aufnehmen kann, werden einige Daten verschüttet.

Führen Sie diese Schritte aus, um einen Seitenprogramm- oder Schreibbefehl auszuführen. Die Seitengröße (normalerweise 256 Byte) und die Sektorgröße (normalerweise 64 KB) sowie die zugehörigen Grenzen sind Eigenschaften des von Ihnen verwendeten SPI-Flashs. Diese Informationen sollten im Datenblatt für den Flash enthalten sein. Ich werde die Details des Ausgleichs der Sende- und Empfangspuffer weglassen.

1) Start with CS_ high.
2) Change CS_ to low.
3) Transmit the Write Enable (WREN) op code.
4) Switch CS_ to high for at least one SPI Bus clock cycle.  This may be tens or
hundreds of host clock cycles.  All write operations do not start until CS_ goes high.  
The preceding two notes apply to all the following 'CS_ to high' steps.
5) Switch CS_ to low.
6) Gadfly loop:   Transmit the 'Read from Status Register' (RDSR) op code and 
one more byte.   Receive two bytes.  First byte is garbage.  Second byte is status.
Check status byte.  If 'Write in Progress' (WIP) bit is set, repeat loop. 
(NOTE:  May also check 'Write Enable Latch' bit is set (WEL) after WIP is clear.)
7) Switch CS_ to high.
8) Switch CS_ to low.
9) Transmit Sector Erase (SE) or Bulk Erase (BE) op code.  If sending SE, then follow
it with three byte address.
10) Switch CS_ to high.
11) Switch CS_ to low.
12) Gadfly loop:  Spin on WIP in Status Register as above in step 6.  WEL will
be unset at end.
13) Switch CS_ to high.
14) Switch CS_ to low.
15) Transmit Write Enable op code (again).
16) Switch CS_ to high.
17) Switch CS_ to low.
18) Gadfly loop:  Wait on WIP bit in Status Register to clear. (WEL will be set.)
19) Transmit Page Program (PP = Write) op code followed by three address bytes.
20) Transmit up to Page Size (typically 256 bytes) of data to write.  (You may allow
Receive data to simply spill over during this operation, unless your host hardware
has a problem with that.)
21) Switch CS_ to high.  
22) SWitch CS_ to low.
23) Gadfly loop:  Spin on WIP in the Status Register.
24) Drain Receive FIFO so that it's ready for the next user.
25)  Optional:  Repeat steps 13 to 24 as needed to write additional pages or
page segments.

Wenn sich Ihre Schreibadresse nicht an einer Seitengrenze befindet (normalerweise ein Vielfaches von 256 Byte) und Sie genügend Daten schreiben, um die folgende Seitengrenze zu überschreiten, werden die Daten, die die Grenze überschreiten sollen, an den Anfang der Seite geschrieben, in der Ihre Programmadresse fällt. Wenn Sie also versuchen, drei Bytes an die Adresse 0x0FE zu schreiben. Die ersten beiden Bytes werden in 0x0fe und 0x0ff geschrieben. Das dritte Byte wird an die Adresse 0x000 geschrieben.

Wenn Sie eine Anzahl von Datenbytes übertragen, die größer als eine Seitengröße sind, werden die frühen Bytes verworfen und nur die letzten 256 (oder Seitengrößen-) Bytes werden zum Programmieren der Seite verwendet.

Wie immer nicht verantwortlich für die Folgen von Fehlern, Tippfehlern, Versehen oder Störungen in den oben genannten oder in der Art und Weise, wie Sie sie verwenden.

Jeff Walther
quelle
"Bevor Sie einen SPI-Flash-Vorgang starten, sollten Sie den Empfangs-FIFO" entleeren ". Dies bedeutet, dass Sie den Status des Empfangspuffers überprüfen und leeren (normalerweise durch" Lesen "des Empfangspuffers), wenn dies nicht der Fall ist bereits leer. Normalerweise schadet das Entleeren (Lesen) eines bereits leeren Empfangspuffers nicht. " Welche Schritte muss ich unternehmen, um den Status des Empfangspuffers zu lesen und den Empfangspuffer zu leeren?
3

Im Gegensatz zu einigen Aussagen hier gibt es zwar einige skurrile SPI-PROMs, aber auch einige Standardanweisungen, die von einer Vielzahl von SPI-PROMs verwendet werden, einschließlich der von Ihnen ausgewählten.

Wie bereits erwähnt, gibt es gute Bit-Bash-Kabel, mit denen SPI direkt programmiert werden kann. In Bezug auf das Signal sieht SPI JTAG sehr ähnlich, daher sollte jeder Bit-Bash-Kabeltyp verwendet werden können, vorausgesetzt, die Schnittstelle ist Open Source. Das interne Protokoll des Flashs ist ziemlich einfach.

Wir verwenden den großen Bruder des Teils, den Sie suchen, um unsere FPGA-Karten (256M - 2G) zu booten. Die Adressierung verfügt über ein zusätzliches Byte für das Speichervolumen, ansonsten sind die Befehle grundsätzlich identisch.

Der von Ihnen verwendete PROM-Typ muss nach Sektoren gelöscht und dann nach Seiten programmiert werden. Das Lesen ist erheblich schneller als das Schreiben (bei den von uns verwendeten kann das Programmieren eine halbe Stunde dauern, das Lesen des gesamten PROM dauert jedoch bei 108 MHz weniger als eine Sekunde).

Nun zu den Befehlen: In diesen Geräten stehen weit mehr Befehle zur Verfügung, als tatsächlich zum Programmieren erforderlich sind. Sie brauchen eigentlich nur folgendes:

  • RDID (Read ID) - nur um das PROM und die Signalisierung zu überprüfen, bevor Sie etwas Komplexeres tun.
  • WREN (Schreibfreigabe) - wird vor jedem Schreibvorgang benötigt.
  • PP (0x02 - Seitenprogramm) - wird zum Programmieren einer Seite benötigt.
  • SE (0x20 - Sektor löschen) - gibt die Bits im Sektor auf '1' zurück.
  • RDSR (0x05 - Lesestatusregister) - wird zur Überwachung des Lösch- / Schreibzyklus benötigt.
  • FREAD (0x0B - schnelles Lesen) - PROM-Daten lesen und Schreibvorgang überprüfen.

Weitere Informationen finden Sie in den Antworthinweisen zur SPI-Programmierung für Xilinx-FPGAs auf deren Website (http://www.xilinx.com). Sie implementieren eine reduzierte Teilmenge von Befehlen, damit ihre FPGAs von diesen Geräten booten können.

Ich habe meinen eigenen Programmierer dafür entwickelt, basierend auf dem, was mir zur Verfügung steht, und ein Programmiererskript in Python geschrieben, aber Sie können dasselbe mit einem Kabel tun. In Ihrem Fall würde ich ernsthaft in Betracht ziehen, alles indirekt über die MCU zu erledigen, wie Michael Karas vorschlägt. Sie müssen nicht das gesamte PROM von der MCU auf einmal programmieren - Sie können dies nach Sektoren tun.

Jxj
quelle
2

Sie sollten in der Lage sein, USBtiny für die Programmierung eines Flash-Speichers anstelle einer Ziel-MCU zu verwenden, wenn Sie die Programmierung ändern möchten. Möglicherweise ist jedoch nicht genügend Speicher vorhanden, um die MCU und den Flash zu programmieren.

Irgendwo habe ich ein Board aus einem Projekt, das sowohl einen ATTINY- als auch einen SPI-Flash hat und als Arduino als leicht verfügbarer "Programmierer" verwendet wird. Eine geringfügige Änderung der ISP-Skizze wird verwendet, um die MCU mit avrdude zu programmieren. Anschließend sendet ein benutzerdefiniertes Dienstprogramm eine Sequenz, die die Skizze in einen speziellen Modus versetzt und Datenblöcke in den SPI-Flash schreibt.

Chris Stratton
quelle