Ich verstehe die Welt seit einigen Stunden nicht mehr. Ich habe Probleme
mit einem simplen SPI Bus und finde einfach nicht die Ursache dafür.
Ich benutzte das stm32 discovery board als SPI Master um Daten zu senden
und zu empfangen.
Folgendes geht:
- CLK ist da
- CS geht
- MOSI funktioniert einwandfrei und die Bits habe ich xmal schon geprüft
und gezählt
- Daten kommen an MISO richtig an!
Ich benutze CooCox als IDE.
Ich habe bereits auch eine Lösung gefunden, allerdings geht die wirklich
nur über CooCox. Nach der SPI Initialisierung setze CPOL und CPHA auf
High über das JTAG-Interface und lasse SPI1 kurz falsch laufen (Nur ein
Frame). Danach setze ich CPOL und CPHA wieder auf 0 und dann
funktioniert alles. Leider finde ich nicht den Grund dafür und ich würde
mich sehr darüber freuen, wenn ich den Controller ohne JTAG Anbindung zu
laufen bekomme ;)
Hier meine GPIO Initialisierung:
1
// GPIO_Pin_5 - SPI1_SCK OUT
2
// GPIO_Pin_6 - SPI1_MISO IN
3
// GPIO_Pin_7 - SPI1_MOSI OUT
4
// GPIO_Pin_10 - // BLOCK-TEST: SPI_CS
5
6
/* Configure SPI1 pins: SCK, MISO and MOSI -------------------------------*/
Eine Kleinigkeit fehlt leider: nämlich was genau nicht funktioniert.
Also was du versuchst, was dabei deiner Ansicht nach passieren sollte
und was tatsächlich passiert.
Und der Code dazu fehlt auch.
Okay...
Was genau nicht funktioniert ist, dass ich keine Daten im
Empfangsregister vorfinde obwohl das richtige Byte an MISO anliegt. Der
Slave funktioniert somit einwandfrei. Ich bekomme die JTAG Lösung auch
nicht per Code nachgestellt. Achselzuck
Es bringt einen nicht immer weiter, nur den Code zu zeigen, in dem man
selbst den Fehler vermutet. Manchmal hilft es, auch den Code zu zeigen,
in dem man ihn nicht vermutet.
Ja die Takte laufen, die Bits in den RCC Registern habe ich auch bereits
geprüft. Ansonsten würde kein SPI Frame nach außen gesendet werden.
Gerne kann ich den Test-Code posten, aber dort vermutlich keine
Probleme. Der Code ist nicht fertig und auch der Stil gefällt mir noch
nicht:
RayOfLight schrieb:> Problem ist genau hier:>> GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Mode habe ich bereits mehrmals gewechselt und dies funktioniert
auch nicht:
Im Internet habe ich bereits unterschiedlichste Meinungen über die
richtige Konfigurationen von MISO gefunden und gefühlt habe ich alles
ausprobiert. Aber ich lasse mich sehr gerne belehren, so ist es ja
nicht.
Bitte beachtet den sehr wichtigen Hinweis, dass die Kummunikation
funktioniert wenn SPI_CPOL und SPI_CPHA über JTAG kurzzeitig auf High
gezogen wird. Warum auch immer ?!?
Die SS Steuerung rund um NSS hat wohl alle irritiert, die je mit STM32
und SPI zu tun hatten. CR1:NSS=1 heisst, dass der interne SS-Pin des SPI
Moduls von CR1:SSI gesteuert wird, an Stelle des externen Pins SS. Und
wenn man einem Master extern SS=0 anlegt, dann nimmt er an, dass ein
anderer Master schneller war als er und schaltet ab. Folglich
funktioniert NSS=1 nur bei SSI=1.
@ A.K.
Diese Aussage habe ich auch öfters im Internet gelesen, dass es wegen
NSS nur Verwirrungen kommt. Ich benutze GPOIA PIN10 als CS und steuere
ihn auch über SW an. Für mich auch kein Problem, da mir die
Geschwindigkeit in dieser Applikation recht egal ist. Andererseits frag
ich mich wirklich was ST sich dabei gedacht hat, aber da scheinen wohl
die alten Thomson Zeiten durch. In Verbindung mit DMA ist die ganze NSS
Steuerung total sinnfrei.
Im übrigen habe ich sogar den neuesten GNU complire installiert, mir
gehen langsam die Ideen aus ;-)
Tim R. schrieb:> Ich benutze GPOIA PIN10 als CS und steuere> ihn auch über SW an.
Ist mir klar. Es geht bei NSS=1 allerdings um das interne SS Signal des
SPI-Moduls. Also das SS Signal, das bei NSS=1 aussen auf dem Pin nicht
aufkreuzt, intern aber dennoch existiert. Wenn diese interne Signal auf
0 steht, dann ist Essig. Und dieses interne Signal ist SSI, bei NSS=1.
Ich mag die STM32 Lib nicht so, also darfst du selber suchen. ;-)
> In Verbindung mit DMA ist die ganze NSS Steuerung total sinnfrei.
Yep.
Was mir noch einfällt, den gesamten Code ohne die Libs zu schreiben.
Damit kannst du einen Softwarefehler besser finden und möglicherweise
den Fehler finden, wenn du im Datenblatt ließt. Mir geht es inzwischen
so, dass ich die Libs garnicht mehr benutze und die Register direkt
beschreibe. Zudem ist der Code damit maximal schnell und mit etwas
Einarbeitung auch übersichtlicher, da man nach verfolgen kann, wann
welches Bit gesetzt/gelöscht wird.
Gruß Jannis
holger schrieb:>> // SPI MODE 3:>> SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;>> SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;>>> Vieleicht möchte das was du da angeschlossen hast> tatsächlich Mode3 haben? Eingestellt ist jedenfalls Mode0.
Soll 0 sein, mein Kommentar habe ich noch nicht zurück geändert.
> Ich mag die STM32 Lib nicht so, also darfst du selber suchen. ;-)
Also das bit SSM und SSI sind bei mir beide auf High.
Zu STM32 Lib: Ich stimme da sehr gerne zu, da vieles kryptisch und als
großes Monster gelöst wurde. Was ich aber mag ist die struct Lösung. Hex
Files noch zur Parametrierung zu nutzen finde ich persönlich als lästig.
>> Vieleicht möchte das was du da angeschlossen hast>> tatsächlich Mode3 haben? Eingestellt ist jedenfalls Mode0.>>Soll 0 sein, mein Kommentar habe ich noch nicht zurück geändert.
Dann muss das wohl ein anderes Problem sein.
Deine Config für Mode0 ist jedenfalls in Ordnung.
Vieleicht liegts auch an der Schaltung.
A. K. schrieb:> SETZ DAS VERDAMMTE SSI BIT!>> Falls meine Erklärung oben zu umständlich gewesen sein sollte. ;-)
In der Tat habe ich das SSi bit wirklich suchen müssen und es wurde
elegant in der Datei stm32f10x_spi.h in diese Zeile versteckt:
1
#define SPI_Mode_Master ((uint16_t)0x0104)
Man beachte 0x100 (SSI bit)
Ach wie ich diese define Programmierung hasse.
A. K. schrieb:> Tim R. schrieb:>> Also das bit SSM und SSI sind bei mir beide auf High.>> Vor oder nach dem Hack?
Vor und wie auch nach dem Hack. Ich habe mal das Register direkt
angesprochen und die Initialisierung ein wenig aufgeräumt. Leider kein
Unterschied:
1
voidinit_SPI1(void)
2
{
3
structSTRUCT_INIT_CR1_SPI{
4
uint16_tCPHA:1;
5
uint16_tCPOL:1;
6
uint16_tMSTR:1;
7
uint16_tBR:3;
8
uint16_tSPE:1;
9
uint16_tLSBFIRST:1;
10
uint16_tSSI:1;
11
uint16_tSSM:1;
12
uint16_tRXONLY:1;
13
uint16_tDFF:1;
14
uint16_tCRCNEXT:1;
15
uint16_tCRCEN:1;
16
uint16_tBIDIOE:1;
17
uint16_tBIDIMODE:1;
18
};
19
20
unionSTRUCT_SPI_CR1{
21
uint16_tall;
22
structSTRUCT_INIT_CR1_SPIbit;
23
};
24
25
unionSTRUCT_SPI_CR1SPI_CR1;
26
27
// SPI MODE Configuration:
28
//
29
// Mode CPOL CPHA
30
// 0 0 0
31
// 1 0 1
32
// 2 1 0
33
// 3 1 1
34
//
35
// 0 SPI_CPOL_Low
36
// 1 SPI_CPOL_High
37
// 0 SPI_CPHA_1Edge
38
// 1 SPI_CPHA_2Edge
39
40
// SPI MODE 0:
41
42
SPI_CR1.all=0;
43
SPI_CR1.bit.CPOL=0;
44
SPI_CR1.bit.CPHA=0;
45
SPI_CR1.bit.DFF=0;// 8-bit data frame format is selected for transmission/reception