Hallo allesamt,
besitzt jemand vielleicht ein Beispielprogramm oder einen Link, wie man
mit einem MSP430 über SPI Daten mit einem FM25L256 (256k FRAM)
austauschen kann? Auch ein Speicher mit ähnlichem Funktionsprinzip wäre
prima. Ich hab zwar einen Quellcode in ASM aufgestellt, aber....nun
ja.... das Ergebnis ist frustrierend.
Vielen Dank schonmal.
Der MSP besitzt ein Hardware SPI. Ich hab mich daher bei TI inspirieren
lassen. Die haben ja zum Thema SPI einige Code Examples. FRAM sollte
richtig angeschlossen sein. Hab mich an die Vorgaben im Datenblatt
gehalten. Die Software wurde folgendermaßen geschrieben:
1) Initialisierung der gesamten Peripherie
2) Senden von WREN OP-Code = Set Write Enable Latch
3) Senden von Write Status Register
4) Senden von 1byte -> BP1 = 0 und BP0 = 0 -> Schreibschutz inaktiv
5) Senden von WREN
6) Senden von Write Memory Data
7) Senden von 16bit Adresse
8) Senden von 8byte Daten
9) Senden von Read Memory Data
10) Senden von 16bit Adresse (die gleiche Adresse)
11) Auslesen des RX Puffers
Insbesondere wurde nach jedem Op-Code Chip Select neu angesteuert, da
dies laut Datenblatt so gewollt ist. Außerdem wurden nach jedem Senden
der TX Puffer überprüft, ob dieser auch wieder bereit ist. Schön sieht
der Code zwar nicht aus, aber Syntax stimmt soweit. Keine Fehler.
Muss ich zwischen den einzelnen Op-Codes noch etwas berücksichtigen?
Müssen evt. irgendwelche Takte dazwischen? Kann ich auch ohne
Oszilosglotz den SPI überprüfen, ob er sich rührt?
Aber ich bin auch für evt. Inspirationen dankbar.
Was heisst nach jedem Opcode?
So
/CS \______/ \_______/ \______/ \______/
WREN WRITE ADDR DATA
oder so
\______/ \_________________/
WREN WRITE ADDR DATA
anderer Fehler könnte auch ein nicht passender SPI-Mode sein.
Zur Not könnte man mit LEDs auf den SPI-Leitungen und einem sehr
langsamen Takt testen.
Laut Datenblatt sind WREN, WRITE_DATA, WRITE_STATUS_REG, READ_DATA usw.
die OP-Codes. Ich meine, bei einem Write_data gehören die Adresse und
die Daten zusammen (Die Adresse allein kann ja kein OP_Code sein). So
hab ich das dann auch im Quellcode gemacht.
Bei Write gehören der Write-Opcode, die Adresse und die Daten zusammen.
Korrektur zum Takt: Es sind laut Errata min. 200kHz nötig, um keine
Einzelbitfehler zu erzeugen!
Hallo, hab jetzt einige neue Sachen ausprobiert. Muss aber gestehen,
dass es immer noch nicht funktioniert. Aber zum SPI hätte ich dann doch
noch eine Frage.
Ich hab den langsamsten Takt für den SPI an meinem MSP430F1611
eingestellt und mir die Signale mit LEDs anzeigen lassen. Am SCK sehe
ich zwar ein blinken, allerdings überrascht mich die lange Pausenzeit.
Der Takt ist pulsartig. Am MOSI meine ich, dass er wohl immer auf HIGH
ist. Bei genauerem betrachteten, hat man allerdings auch das Gefühl,
dass die LED auch mal ausgeht. Und zwar genau dann, wenn SCK einen Puls
rausschickt.
Ist das so wirklich normal? Habe leider keine Zeitdiagramme rausgoogeln
können. Nichts gefunden. Aber nach den gängigen Leitungscodierungen
sieht das jedenfalls nicht aus.
Im übrigen ist MISO auch immer auf HIGH (oder scheint zumindest so)
Ist es vielleicht möglich MOSI und MISO zu verbinden, um zu überprüfen
ob RX das gleiche empfängt was TX sendet, oder wird das nicht
funktionieren?
Wie dann und was nun?
Ach ja, SPI Mode stellt man mit CKPH & CKPL im U0TCTL ein, oder? Nur
kurz zur Bestätigung. Danke
Nun, ich hab mich an die Codebeispiele von TI gehalten. Hab nur drei
Zeilen geändert. Die Adresse des StackPointers, den Header und die
Startadresse des Codes. Und soweit ich das beurteilen kann, sind die
Beispiele logisch initialisiert. Wie schon gesagt... Mittels LEDs sehe
ich, dass was an den SPI Ports passiert. PxSEL muss also schon mal
stimmen, da ich sonst keine Zustandsänderungen an den Ports hätte. Nur
was da passiert scheint mir nicht logisch.
@ arc
Meintest mit SPI-Mode ist soweit i.O.....CKPH & CKPL bestimmen den
Mode? Wenn ja, ich habs mittlerweile mit allen Kombinationen probiert.
Um auf die Frage von vorhin einzugehen. Kann ich RX & TX zum Testen
verbinden oder gebe es da noch was zu berücksichtigen? Wir fällt leider
keine bessere Möglichkeit ein ohne wieder Geld und Zeit irgendwo
liegenzulassen.
Die Richtung der Ports muss - zusätzlich zu PxSEL - immer passend
gesetzt werden!
Also min. P3DIR = P3DIR_1 | P3DIR_3 und Slave Transmit Control
ausschalten U0TCTL = STC | ..., falls dort was am Port hängt.
MISO/MOSI kann man zum Testen verbinden
Okay, also ich hab jetzt mal die Gewissheit, dass mein SPI einwandfrei
funktioniert. Obwohl mir die Leitungskodierung sehr spanisch vorkommt.
Nun egal, es läuft ja.
Weshalb will nun mein FRAM nichts machen das bleibt das große Rätsel
!!!
Ich setzt mal ein Bild der Verschaltung rein. Vielleicht hab ich ja
wirklich schon da Mist gebaut. Was allerdings sehr tragisch ist, da die
Platine so schon fertig ist. Nun, was aber sein muss muss sein.
Nun für alle anderen Interessenten, die auf der Suche nach einem SPI
Code sind ich stell mal meinen rein Auf meinem MSP430F1611
funktionierts.
#include <msp430x16x.h>
;***********************************************************************
***************************************
ORG 04000h ; Progam Start
;***********************************************************************
***************************************
RESET mov.w #03900h,SP ; Initialize stackpointer
StopWDT mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop watchdog timer
SetupP3 bis.b #0Eh,&P3SEL ; P3.1-3 SPI option select
SetupSPI bis.b #USPIE0,&ME1 ; Enable USART0 SPI mode
bis.b #CKPH+SSEL1+SSEL0+STC,&UTCTL0 ; SMCLK, 3-pin mode
bis.b #CHAR+SYNC+MM,&UCTL0 ; 8-bit SPI Master
**SWRST**
mov.b #02h,&UBR00 ; SMCLK/2 for baud rate
clr.b &UBR10 ;
clr.b &UMCTL0 ; Clear modulation
bic.b #SWRST,&UCTL0 ; **Initialize USART state
machine**
;
Mainloop call #RXTX ; Exchange data
Delay push.w #0 ; Software delay
D1 dec.w 0(SP) ;
jnz D1 ;
incd.w SP ;
jmp Delay ;Mainloop ; Repeat
;
;-----------------------------------------------------------------------
-------
RXTX; URXBUF0 UTXBUF0
;-----------------------------------------------------------------------
-------
TX0 bit.b #UTXIFG0,&IFG1 ; USART0 TX buffer ready?
jz TX0 ; Jump --> TX buffer not
ready
bic.b #URXIFG0,&IFG1 ; Clear RXBUF flag
mov.b #0x5F,&TXBUF0 ; Dummy write to start
SPI
L1 bit.b #URXIFG0,&IFG1 ; RXBUF ready?
jnc L1 ; 1 = ready
mov.b &RXBUF0,R10 ; ????? SURPRISE
ret ; Return from subroutine
;
;-----------------------------------------------------------------------
-------
; Interrupt Vectors
;-----------------------------------------------------------------------
-------
ORG 0FFFEh ; MSP430 RESET Vector
DW RESET ;
END
Das stimmt, dass die Portrichtungseinstellung für PORT3 fehlt.
Allerdings funktioniert es auch ohne diese Einstellung. Im Datenblatt
wird zwar darauf hingewiesen, dass die Portrichtung durch PxSEL nicht
automatisch eingestellt wird, aber ich zitieren auch mal folgende
Passage aus dem Datenblatt:
"Setting PxSELx = 1 does not automatically set the pin direction.
Other peripheral module functions may require the PxDIRx bits to be
configured according to the direction needed for the module
function."
Für SPI speziell ist es anscheinend nicht erforderlich. Hab es mit und
ohne PxDIR ausprobiert und beides hat funktioniert (SPI ohne FRAM).
Übrigens hab ich SPI auch mit allen Möglichkeiten (CKPL & CKPH gesetzt
und nicht gesetzt) mit dem FRAM ausprobiert. Immer das gleiche
deprimierende Ergebnis
Mir ist gerade etwas aufgefallen.
Was ich noch nicht ausprobiert hatte, ist die Taktquelle zu ändern.
Hatte standardmäßig den SMCLK benutzt. An XT2IN/OUT hab ich allerdings
nur einen 32kHz Quarz angeschlossen. An XIN/OUT hängt jedoch ein 8MHz
Quarz. Ich war die ganze Zeit der Meinung, dass ich von diesem meinen
Takt herbekomme. Jetzt sehe ich im Datenblatt, dass SPI seinen Takt
aber nur vom 32kHz Quarz bekommen kann.
So, jetzt bin ich aber mal gespannt....
Also jetzt bin ich total verwirrt. Wenn ich SPI auf ACLK konfiguriere,
dann bleibt er mir im Programmcode hängen. Und zwar immer dann, wenn
ich den Puffer von TX/RX überprüfe. Er bleibt dann einfach in der
Schleife hängen, bei der der Puffer geprüft wird, ob er wieder bereit
ist. Jetzt kommt das lustige Wenn ich SPI auf SMCLK konfiguriere, dann
kann ich mir zumindest selbst Daten schicken. Auf ACLK bleibt er
hängen. ABER: Wenn ich mir im BCSCTL1 (Basic Clock System Control
Register 1) das XT2OFF Bit anschaue, dann dürfte XT2=SMCLK gar nicht an
sein. Aber nur mit meinem angeblich eingeschalteten SMCLK funktioniert
mein SPI (SMCLK für SPI konfiguriert)
Aber es geht noch weiter:
Stell ich im BCSCTL1 den Teiler für ACLK ein(z.B. Teiler 8),dann ist
SMCLK plötzlich wieder an (XT2 laut Control Register) . SPI
funktioniert aber NUR wieder, wenn der Takt auf SMCLK konfiguriert ist.
Nicht aber bei ACLK....**Verkehrte Welt**....
Nun denn, nach weiterem rumsuchen fällt mir auf, dass der DCO an ist.
Aus welchen Gründen auch immer. Aha, neue Hoffnung, von da bekommt der
SMCLK also seinen Takt. Dann wäre mal geklärt, warum SPI überhaupt
funktioniert. Also, ich dann mal schnell DCO auf schnellste Freq
eingestellt, FRAM ausprobiert nichts geht. Aber SPI an sich
funktioniert immerhin. Habs ausprobiert.
So, und jetzt???
Was für Probleme hat mein FRAM
Ich glaube, ich weiß was es ist. Hab mir in der Zwischenzeit ein Oszi
besorgt.
Jetzt brauche ich einen SPI Profi !!!!!
Folgende Beobachtung. Laut Datenblatt des FRAM benötige ich eine Data
Setup Time und eine Setup Hold Time von 5ns. Also 5ns bevor die
steigende Taktflanke kommt muss das Data Signal schon da sein. Und 5ns
nach der steigenden Taktflanke muss das Data Signal auch noch da sein.
Mein MSP420F1611 macht aber folgendes. Die Pegel des Data Signals (TX)
fallen oder steigen exakt bei den steigenden Taktflanken. Ändere ich
das CKPH Bit habe ich das gleiche Problem nur exakt bei den fallenden
Taktflanken. Ich brauche daher irgendeine Phasenverschiebung. Im
übrigen...wenn ich das CKPH oder/und das CKPL Bit ändere habe ich nur
diese beiden Ergebnisse.
Was kann ich beim SPI machen, dass die Setup und Hold Zeiten
eingehalten werden?
Ich möchte aber schon beim SPI bleiben und es nicht über Ports,Timer
etc. machen.
Irgendwelche Ideen?
Na das ist doch OK. Wenn der FRAM die steigende Flanke zum Daten
übernehmen nimmt, dann änder doch den CKPH so, dass der MSP die Daten
zur fallenden Flanke aktualisiert. Die Daten stehen dann stabil zur
steigenden Flanke (und danach) an.
Im übrigen ist es keine gute Idee, an den XT2 einen 32Khz Quarz
anzuschließen, da der Oszillator auf Frequenzen zwischen 455Khz und
8MHz ausgelegt ist. Die Standardbeschaltung wäre, den 32KHz an XT und
den 8MHz an den XT2.