Hallo,
ich möchte mit einen atmega2560 einen F-RAM (FM25H20 mit 2Mb Serial 3V)
via SPI betreiben. Bisher sind meine Versuche nicht gerade von Erfolg
gekrönt.
Der Atmega wird mit einen externen 8 MHz Quarz betrieben.
Der FRAM FM25H20 unterstützt: Very Fast Serial Peripheral Interface -
SPI
• Up to 40 MHz Frequency
• Direct Hardware Replacement for Serial Flash
• SPI Mode 0 & 3 (CPOL, CPHA=0,0 & 1,1)
[http://www.ramtron.com/files/datasheets/FM25H20_ds.pdf]
-kurze Pinbelegung am Atmega:
PB3(MISO),
PB2(MOSI),
PB1(SCK),
PB6(/CS) vom FRAM (low active)
Meine SPI Initialisierung lautet:
Mit diesen Code-Zeilen kann ich an Adresse 0 und 1 Daten auslesen -->
also muss bei meinen anfänglichen Versuchen ein "Code-Geschnipsel"
erfolgreich gewesen sein. Demnach würde jetzt das Schreiben nicht mehr
funktionieren.
Hat Jemand eine Idee was hier falsch ist oder vergessen wurde? Hat
jemand Erfahrungen mit diesen FRAM - vielleicht habe ich im Datenblatt
irgendwas überlesen???
Gruß Torsten
Du musst das WREN vor jedem(!) Schreibzugriff senden. Das Flag wird nach
einem Schreibzugriff automatisch zurückgesetzt. Das machen alle
SPI-EEPROMS und Flashes so.
fchk
Probier mal Mode 3. Ich war bei einem AVR, der ein Atmel Dataflash, ein
FRAM und ein ENC28J60 an seinem SPI hängen hat, über SPI-Probleme
gestolpert. Zwar konnten alle offiziell den SPI Mode 0, aber eines davon
bewies eine etwas andere Ansicht dazu, indem die Bits dabei um eine
Position verrutschten. Ich weiss nur grad nicht mehr, welches der 3
SPI-Devices das war.
das Auslesen scheint zu funktionieren - aber nicht das Schreiben....
Habe leider keine Ahnung mit welchen Code-Zeilen bzw. mit welcher
Prozedur das Schreiben funktioniert hat. Wahrscheinlich hat da das
Auslesen nicht funktioniert und deshalb wurde der Code von mir
verworfen.
Ich werde mal die Frequenz verringern......
Frank K. schrieb:> Du musst das WREN vor jedem(!) Schreibzugriff senden.
Das ist ein weit verbreiteter Irrtum. Hierzu das Datenblatt:
1
Sending the WREN op-code causes the internal Write
2
Enable Latch to be set. A flag bit in the Status
3
Register, called WEL, indicates the state of the latch.
4
WEL=1 indicates that writes are permitted.
Fazit: einmal gesetzt bleibt das Write Enable gesetzt, bis die Spannung
weg geht oder ein WRDI - Write Disable gesendet wird.
A. K. schrieb:> Probier mal Mode 3.
Ich würde jetzt auch mal das Bit-Timing nochmal genau anschauen. Nicht
alle SPI-Devices Schieben auf der einen und Latchen auf der anderen
Flanke...
Insbesondere würde ich mich auf solche expliziten Angaben (CPOL,
CPHA=0,0 & 1,1) nicht verlassen. Nicht alle Hersteller haben diese Bits
gleich implementiert. Da hilft nur das Vergleichen der Timing-Diagramme
der beiden betroffenen Komponenten (uC und FRAM)...
EDIT:
> Ich werde mal die Frequenz verringern......
Das wird nicht nötig sein, denn 4MHz << 40MHz.
Wenn es aber eine Änderung bringt, dann zurück zum Bittiming...
Ein paar Punkte:
- das Verändern der Pin-Zustände (SCK, MISO, MOSI) zusammen mit CS
sollte man grundsätzlich vermeiden d.h. erst /CS auf High dann die Ports
initialisieren, dann SPI initialisieren, dann irgendwann die
Kommunikation mit dem externen Baustein.
- beim Lesen wird ein Byte zuviel gelesen bzw. das erste wird verworfen
1
SPITransceive(uint8_tvalue){
2
SPDR=value;
3
while((SPSR&0x80)==0x00);
4
returnSPDR;
5
}
6
7
voidFRAMSelect(void){
8
...
9
}
10
11
voidFRAMDeselect(void){
12
...
13
}
14
15
// dann können die anderen Befehle einfach zusammengesetzt werden
Lothar Miller schrieb:> Frank K. schrieb:>> Du musst das WREN vor jedem(!) Schreibzugriff senden.> Das ist ein weit verbreiteter Irrtum. Hierzu das Datenblatt:>
1
> Sending the WREN op-code causes the internal Write
2
> Enable Latch to be set. A flag bit in the Status
3
> Register, called WEL, indicates the state of the latch.
4
> WEL=1 indicates that writes are permitted.
5
>
> Fazit: einmal gesetzt bleibt das Write Enable gesetzt, bis die Spannung> weg geht oder ein WRDI - Write Disable gesendet wird.
Ich lese aber auch:
1
Write Operation
2
All writes to the memory array begin with a WREN
3
op-code. The next op-code is the WRITE instruction.
4
This op-code is followed by a three-byte address
5
value, which specifies the 18-bit address of the first
Frank K. schrieb:> Write Operation> All writes to the memory array begin with a WREN> op-code. The next op-code is the WRITE instruction.> This op-code is followed by a three-byte address> value, which specifies the 18-bit address of the first> data byte of the write operation.
werde ich gleich ausprobieren.....habe danach die Start-addresse nicht
gesendet
Arc Net schrieb:> Ein paar Punkte:> - das Verändern der Pin-Zustände (SCK, MISO, MOSI) zusammen mit CS> sollte man grundsätzlich vermeiden d.h. erst /CS auf High dann die Ports> initialisieren, dann SPI initialisieren, dann irgendwann die> Kommunikation mit dem externen Baustein.> - beim Lesen wird ein Byte zuviel gelesen bzw. das erste wird verworfen
Ich habe jetzt mal diesen Code ausprobiert und erhalte das Gleiche
Ergebnis - ich kann an Addr 0 und 1 die Werte auslesen aber nicht
schreiben. Trotzdem Danke!!!
1
unsignedcharSPITransceive(unsignedcharvalue){
2
SPDR=value;
3
while((SPSR&0x80)==0x00);
4
returnSPDR;
5
}
6
7
voidFRAMSelect(void){
8
PORTB&=~(1<<PB6);
9
}
10
11
voidFRAMDeselect(void){
12
PORTB|=(1<<PB6);
13
}
14
15
// dann können die anderen Befehle einfach zusammengesetzt werden
>werde wohl weiter herumexperimentieren müssen....
Wie wäre es lieber mit nachdenken?
>void fram_spi_init(unsigned char data_direction)>{> PORTB &= ~((1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB6));
Warum löschst du PB3, wenn es MISO ist? Wozu überhaupt die Zeile? Du
nutzt doch Hardware SPI, also lass die Pins in Ruhe das machen, was die
Hardware machen muss.
>Write Operation>All writes to the memory array begin with a WREN>op-code.
Das ist falsch. Ein Mal setzen reicht.
Frank K. schrieb:> Lothar Miller schrieb:>> Frank K. schrieb:>>> Du musst das WREN vor jedem(!) Schreibzugriff senden.>> Das ist ein weit verbreiteter Irrtum. Hierzu das Datenblatt:>> Fazit: einmal gesetzt bleibt das Write Enable gesetzt, bis die Spannung>> weg geht oder ein WRDI - Write Disable gesendet wird.>> Ich lese aber auch:> fchk
oder den gesamten Abschnitt lesen (scnr)
"WREN - Set Write Enable Latch
Sending the WREN op-code causes the internal Write
Enable Latch to be set. A flag bit in the Status
Register, called WEL, indicates the state of the latch.
WEL=1 indicates that writes are permitted.
Attempting to write the WEL bit in the Status
Register has no effect on the state of this bit – only
the WREN op-code can set this bit.
The WEL bit will be automatically cleared on the rising edge of /S
following a WRDI, a WRSR, or a WRITE operation.
This prevents further writes to the Status Register or
the F-RAM array without another WREN command.
Figure 5 below illustrates the WREN command bus
configuration."
Kurz gesagt: Alle Write-Befehle nach einem WREN setzen den Schreibschutz
wieder, alle Read-Befehle lassen ihn unangetastet.
Ähnliches gilt z.B. für M25P, M25PX, SST25 (da muss nach dem Power-On
auch der Schreibschutz für die Blöcke aufgehoben werden), AT25, 25AA/LC
Frank K. schrieb:> Write Operation> All writes to the memory array begin with a WREN> op-code. The next op-code is the WRITE instruction.> This op-code is followed by a three-byte address> value, which specifies the 18-bit address of the first> data byte of the write operation.
geht immer noch nicht
Andreas schrieb:> Hast du schon mal das Statusregister ausgelesen, ob WEL auch gesetzt> ist?> Der Chip hat auch eine Schreibschutzfunktion (BP0, BP1)...
Habe vergessen Deine Frage zu beantworten...
Das Status Register hat immer den Inhalt 1100 0000b auch wenn ich es
nach einem Schreibversuch auslese, sogar nach dem power-up!??
----------------------------------------
Table 2. Status Register
Bit 7 6 5 4 3 2 1 0
Name WPEN 1 0 0 BP1 BP0 WEL 0
Torsten Albrecht schrieb:> ----------------------------------------> Table 2. Status Register> Bit 7 6 5 4 3 2 1 0> Name WPEN 1 0 0 BP1 BP0 WEL 0
WPEN = Write Protect Enable
Im Statusregister ist Bit7 gesetzt. Noch Fragen? Erstmal solltest du den
FRAM aus dem Write Protect rausholen, danach kannst du auch schreiben.
Frank Bär schrieb:> WPEN = Write Protect Enable>> Im Statusregister ist Bit7 gesetzt. Noch Fragen? Erstmal solltest du den> FRAM aus dem Write Protect rausholen, danach kannst du auch schreiben.
Habe mich falsch ausgedrückt, nachdem ich einmalig den OP-Code WREN
gesendet habe, steht im Register 1100 0010. siehe Tabelle
Table 4. Write Protection
WEL WPEN /W Protected Blocks Unprotected Blocks Status Register
1 1 1 Protected Unprotected Unprotected
demnach sollte das Schreiben möglich sein! Geht aber nicht!!!