SPI-Flash-Speicher mit ATMega1284

Ich habe einen SST26VF064B 8 MB Flash-Speicher-IC an einen ATMeag1284 angeschlossen, wie im folgenden Diagramm gezeigt. Mein Plan ist, mit ihm über SPI zu sprechen.

SchemaBeachten Sie, dass alle Kondensatoren im Schema 100 nF haben.

Beim Auslesen der JEDEC-ID erhalte ich nicht die erwarteten Werte. Zuerst setze ich die SS-Leitung auf Low, sende dann den Befehl 0x9F, lese dann 3 Bytes (durch Senden von 0xffDummy-Daten) und ziehe schließlich die SS-Leitung wieder auf High. Das Datenblatt0xBF 0x26 0x43 sagt mir, dass die ID für das spezifische Gerät sein sollte, das ich habe (siehe Seite 24). Ich vermute, dass etwas mit meiner SPI-Verbindung nicht stimmt. Der Oszilloskop-Messwert der SCK-, MOSI- und SS-Leitung sieht jedoch wie erwartet aus. Außerdem dekodiert mein Code das Muster in der MISO-Zeile korrekt als 0x7c 0x20 0x6f. Unten finden Sie die Oszilloskop-Messwerte.

0x05Außerdem habe ich versucht, den Status und die Konfiguration mit den jeweiligen Befehlen auszulesen 0x35. Beide kehren jedoch nur zurück 0x00. Laut Datenblatt sollte zumindest das Konfigurationsregister in der Werkseinstellung am 3. Bit eine 1 enthalten.

Der folgende Code wird auf dem ATMega1284 ausgeführt:

#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>

void setSSLow() {
    // Drive SS to low
    PORTB &= ~(1<<PINB4);
}

void setSSHigh() {
    // Set SS to high
    PORTB |= (1<<PINB4);
}

void SPI_MasterInit(void)
{
    // Set SS, MOSI and SCK output, all others input
    DDRB = (1<<PINB4)|(1<<PINB5)|(1<<PINB7);
    setSSHigh();

    // Enable SPI, Master, set clock rate fck/128 
    // Sample on rising edge, output on falling
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1)|(0<<CPHA)|(0<<CPOL);
}

char SPI_MasterTransmit(char cData)
{
    // Start transmission 
    SPDR = cData;
    // Wait for transmission complete
    while(!(SPSR & (1<<SPIF))) ;

    char receivedData = SPDR;
    return receivedData;
}

char buffer[3];

int main(void)
{
    SPI_MasterInit();

    // Send 'Read JEDEC ID' command
    setSSLow();
    char status = SPI_MasterTransmit(0x9f);

    // Get data
    for (int i=0; i<3; i++) {
        char data = SPI_MasterTransmit(0xff);
        buffer[i] = data;
    }
    setSSHigh();

    _delay_ms(1000);

    while (1) {
        // Do nothing
    }
}

SCK und SS Uhr und SS

SCK und MOSI Uhr und MOSI

SCK und MISO Uhr und MISO

Ich bin jetzt an einem Punkt angelangt, an dem mir nichts anderes einfällt, um zu versuchen, dieses Problem zu beheben. Ich wäre sehr hilfreich für jede Hilfe, die Sie leisten können! Dies ist das erste Mal, dass ich SPI verwende, und es ist sehr schwierig für mich, Hardware zu debuggen, da ich einen Softwarehintergrund habe.

AKTUALISIERUNG 1

Ich habe heute alles noch einmal überprüft und für mich sieht alles richtig aus. Beim Lesen der JEDEC-ID erhalte ich jedoch immer noch die gleiche Ausgabe. Wie in den Kommentaren unten erwähnt, handelt es sich um eine sich wiederholende Bytefolge:

7c 20 6f 84 0d f0 81 be 10 37 c2 06 f8 40 df 08 1b e1 03

Da ich den gleichen Chip im 16-Pin-Gehäuse hatte, lötete ich schnell eine Breakout-Platine zusammen und ersetzte den Chip. Überraschenderweise bekomme ich genau das gleiche Verhalten. Ich denke definitiv, dass etwas falsch ist, wie ich es mache, aber ich sehe noch nicht, wie ...

AKTUALISIERUNG 2

Wie ich bereits in den Kommentaren erwähnt habe, habe ich es geschafft, den Speicherchip mit einem Arduino zum Laufen zu bringen. Also habe ich weiter recherchiert. Ich habe den Code, den ich auf dem ATMega1284 verwendet habe, direkt auf den Arduino geladen. Und raten Sie mal: Es funktionierte out of the box. Also muss mit dem ATMega, den ich verwende, etwas nicht stimmen. Außerdem habe ich schnell eine Software-SPI-Implementierung geschrieben, bei der andere Pins verwendet wurden als die, die vom Hardware-SPI verwendet werden. Und das funktioniert auch. Ich werde versuchen, einen anderen ATMega1284 in die Hände zu bekommen und es mit diesem versuchen. Ich vermute, dass ich etwas im ATMega1284 kaputt gemacht habe ...

AKTUALISIERUNG 3

Aus Versehen habe ich es gerade geschafft, mit dem SSTV26 über Hardware-SPI auf dem ATMega1284 zu kommunizieren. Ich hatte immer noch Kabel an SS, MOSI und SCK angeschlossen, die mit nichts anderem verbunden waren. Wenn ich diese Kabel berühre, funktioniert die Kommunikation. Wenn ich sie nicht anfasse, funktioniert es nicht. Ich vermute, da schwimmt etwas. Das Werkzeug habe ich gerade nicht zur Hand.

Kurz gesagt: Ihr Problem ist, dass der Flash-Chip unerwartete Daten zurückgibt?
Richtig. Auf wiederholbare Weise. Dh die zurückgegebenen Daten sind immer gleich.
Nichts springt mir als falsch ins Auge. Ihre Pinbelegung stimmt, und die O-Scope-Aufnahmen sehen gut aus. Die erwarteten Daten und die tatsächlichen Daten scheinen keine Beziehung zu haben (wie um ein Bit verschoben oder LSB anstelle von MSB). Überprüfen Sie, ob Sie den Flash-Chip haben, von dem Sie denken, dass Sie ihn haben, falls Sie ihn noch nicht haben.
Danke, dass Sie es sich angesehen haben. Ich schätze es sehr! Das ist sehr seltsam. Ich habe doppelt überprüft, ob ich tatsächlich das Teil habe, von dem ich glaube, dass ich es habe. Alles entspricht dem Datenblatt. Weitere Untersuchungen ergaben, dass die vom Chip zurückgegebene Sequenz eine 18-Byte-Sequenz ist, die mit den Bytes 0x7c 0x20 0x6f beginnt (wie oben erwähnt). Wenn ich einfach weiterlese, werden diese 18 Bytes wiederholt. Ich werde morgen nochmal alles prüfen. Wenn ich immer noch das gleiche Problem habe, werde ich mich an Microchip wenden.
Ich würde gerne ein Update hören, wenn Sie es herausfinden.
Ich werde tun. Ich gebe noch nicht auf. Das muss funktionieren...
"Die vom Chip zurückgegebene Sequenz ist eine 18-Byte-Sequenz, die mit den Bytes 0x7c beginnt ..." - aber die Sequenz, die Sie uns jetzt zeigen, ist 19 Bytes?
Du hast natürlich recht. Byte-Array-Index 0-18 = 19 Bytes ... Danke für die Hinweise!
Update 3: Klingt dann nach Wackelkontakten. Ich verdrahte Sachen mit Buchsen oder Buchsenleisten auf Insel-Loch-Perfboards (Velleman ECS1/2, ist vielleicht etwas teurer, aber es ist das Beste - großartige Lochausrichtung, gute Pads zum Löten und die Boards sind nicht verzogen - plus sie sind 80 x 100 mm, die gleiche Größe wie die kostenlose Version der von Eagle unterstützten Platinen, wenn Sie bereit sind, eine Leiterplatte zu erstellen) im Vergleich zu dem Versuch, die Dinge auf lötfreien Steckplatinen am Laufen zu halten. Viel weniger Ärger.

Antworten (2)

Das zugrunde liegende Problem hatte nichts damit zu tun, dass die Software nicht richtig funktionierte oder die Chips nicht richtig funktionierten. Ich habe 20-cm-Flachbandkabel verwendet, um den ATMega1284 mit der externen Platine zu verbinden, die den Speicherchip enthält. Die Kabel zu trennen und sie ein wenig zu spreizen, löste die Probleme. Ich hatte wahrscheinlich ein Übersprechen zwischen den Signalen. Die O-Scope-Messungen vom ersten Post wurden sehr nahe am ATMega1284 durchgeführt, wo der Effekt höchstwahrscheinlich nicht sichtbar war. Um sicherzustellen, dass dies in meinem Entwicklungsaufbau nicht wieder vorkommt, habe ich die Kabel auf etwa 4 cm gekürzt. Ich hatte bisher keine weiteren Probleme.

Vielen Dank an alle, die sich die Zeit genommen haben, es sich anzusehen! Ich schätze es wirklich!

Zu lange für einen Kommentar, haben Sie versucht, einen Reset-Befehl zu senden?

5.2 Reset-Enable (RSTEN) und Reset (RST) Der Reset-Vorgang wird als System-(Software-)Reset verwendet, der das Gerät in den normalen Betriebsbereitschaftsmodus versetzt. Diese Operation besteht aus zwei Befehlen: Reset-Enable (RSTEN) gefolgt von Reset (RST). Um den SST26VF064B/064BA zurückzusetzen, treibt der Host CE# auf Low, sendet den Reset-Enable-Befehl (66H) und treibt CE# auf High. Als nächstes treibt der Host CE# wieder auf Low, sendet den Reset-Befehl (99H) und treibt CE# auf High, siehe Abbildung 5-1.

Der Reset-Vorgang erfordert den Reset-Enable-Befehl gefolgt vom Reset-Befehl. Jeder andere Befehl als der Reset-Befehl nach dem Reset-Enable-Befehl deaktiviert Reset-Enable.

Sobald die Reset-Enable- und Reset-Befehle erfolgreich ausgeführt wurden, kehrt das Gerät in den normalen Lesemodus zurück und führt dann Folgendes aus: setzt das Protokoll in den SPI-Modus zurück, setzt die Burst-Länge auf 8 Bytes zurück, löscht alle Bits außer Bit 4 (WPLD) und Bit 5 (SEC) im Statusregister auf ihre Standardzustände und löscht Bit 1 (IOC) im Konfigurationsregister auf seinen Standardzustand. Ein Geräte-Reset während eines aktiven Programmier- oder Löschvorgangs bricht den Vorgang ab, was dazu führen kann, dass die Daten des Zieladressbereichs beschädigt werden oder verloren gehen. Abhängig von der vorherigen Operation kann der Reset-Zeitpunkt variieren. Die Wiederherstellung nach einer Schreiboperation erfordert eine längere Latenzzeit als die Wiederherstellung nach anderen Operationen. Siehe Tabelle 8-2 auf Seite 49 für Reset-Timing-Parameter

Obwohl es keine schlechte Idee ist, Dinge auszuprobieren, sollte dies nicht erforderlich sein, insbesondere um lediglich das Chip-ID-Register zu lesen.
Es wäre schön, einen Befehl auszuprobieren, der den Zustand des Geräts auf offensichtliche Weise ändert, um zu sehen, ob das Gerät Befehle überhaupt erkennt. Leider wird das Zurücksetzen keine offensichtliche Änderung vornehmen.
Die Umstellung auf Quad-SPI könnte funktionieren. Der Host würde den resultierenden Datenverkehr nicht erkennen, aber die Überwachung auf dem o-Scope würde zeigen, ob Datenverkehr auf den zusätzlichen IOs angezeigt wird.
Ich habe versucht, etwas an eine zufällige Speicheradresse zu schreiben und erneut zu lesen. Ich bekomme die Bytes, die ich geschrieben habe, nicht zurück. Ich werde das versuchen und sehen, ob ich nach dem Umschalten zusätzliche Daten auf den anderen Datenleitungen erhalten kann.
Ich habe herausgefunden, dass der Speicher-IC wie erwartet funktioniert. Ich habe es heute mit einem Arduino verbunden und die SPI-Bibliothek verwendet, um mit dem Chip zu sprechen. Innerhalb der ersten 20 Minuten hat es funktioniert. Als nächstes habe ich den Code, den ich auf dem ATMega verwende, auf den Arduino hochgeladen. Und hier wird es seltsam. Das geht auch! Ich vermute jetzt, dass der ATMega irgendwie beschädigt ist. Ich werde versuchen, einen anderen Chip in die Hände zu bekommen und sehen, ob das funktioniert.
Siehe mein Update oben. Ich konnte das Problem deutlich reduzieren.