Hat von Euch jemand eine Idee, weshalb ich das SPI2 des STM32G474 nicht
einschalten kann. Bevor ich Zeile 63 ausführe, steht im CR1-Register
0x2C,
nach Ausführung der Zeile 63 nicht wie erwartet 0x6C, sondern 0x28 -
anstatt dass das SPE-Bit gesetzt wird, wird das MSTR-Bit gelöscht!
Danke für alle Hinweise!
Uli N. schrieb:> wird das MSTR-Bit gelöscht!
Bevor du mit einzelnen Bitmanipulationen arbeitest benutze
doch die vielen LL-Macros und -Funktionen aus der STM Lib
um deine Hardware zu setzen. Bei deinen selbstgestrickten
Setzfunktionen kannst du nicht sicher sein ob du alle
Registerzugriffe immer richtig machst. Ich tu mir diese
Bit-Fummelei und deren Überprüfen jedenfalls nicht an.
CubeMx bietet auch (auch für LL) eine excellente generierte
Initialisierung an bei der dann nichts schiefgeht ....
Kann auch vorkommen dass eine bestimmte von dir gewünschte
Konfiguration nicht funktioniert weil die Mehrfachbelegung
der I/O Resourcen das gerade nicht zulässt. CubeMx würde
dir so einen Konflikt mitteilen. HAL muss ich nicht haben
aber CubeMx macht einem das Leben leichter!
Gute Idee - werd' ich am Montag gleich mal testen!
Vermute aber, dass das Ergebnis genauso sein wird, da ich mir auch schon
den Assemler-Code angeschaut habe - den behersche ich zwar nicht, aber
zumindest war schon mal soviel zu sehen dass zu einem Register 0x40
"ge-or-t" und nicht
etwa 0x04 "ge-and-et" wird.
Hallo,
pSPI->CR1 = .. ist Absicht, oder?
Nicht das Du eigentlich pSPI->CR1 |= .. meinst.
Ansonsten doch einfach STM32CubeIDE im Debug Modus.
Da kannst Du per F5 die Befehle nacheinander durch takten.
Jogibär
PS: Bin auch kein Fan von HAL
Ist ein ODER nicht richtig?
Du willst doch zusätzlich ein Bit setzen?
0x40 ist schon Bit Nr. 6
Ja in Zeile 45 ist pSPI->CR1 = .. Absicht - möchte alle Bits des
Registers entsprechend den davor stehenden Kommentaren setzen.
Und genau das mach' ich doch - in der STM32CubeIDE im Debug Modus mit F5
Zeile 63 ausführen - und die Bilder zeigen die SPI2-Register vor und
nach diesem Schritt.
Ja, ein OR sollte richtig sein.
Will den SPI ohne DMA und ohne Interrupts betreiben - die Konfiguration
der IO-Pins kann ich am Montag noch nachreichen, denke aber, das selbst
eine noch so blöde Konfiguration selbiger keinen Einfluss auf das Setzem
des SPI2-Enable-Bits haben sollte, eher schon eine "verquerte"
Konfiguration des SPI-Devices selbst - und die sollte aus den paar
Initialisierungsbefehlen ersichtlich sein.
Habe das Programm zunächst parallel in einer CubeMX- und einer
bare-metal Version entwickelt - letzter Stand war da 28k zu 4k Code-Size
(bisher hauptsächlich Initialisierungscode) - mit CubeMX wird letztlich
kaum ein Bootloader und zweimal die Applikations in die 128kB Variante
passen, deshalb jetzt die Konsentration auf die bare-metal-Version.
Das Bit SPE wird gesetzt (allerdings bei SPI1).
Eventuell liegt es dem verwendeten Prozessor.
Ich würde mir mal das Datenblatt genauer ansehen.
Mit welchen Parametern rufst Du eigentlich die spiConfig auf?
Dein SPI_TypeDef ist ja aus der .h Datei der CPU, oder?
1
typedefstruct
2
{
3
__IOuint32_tCR1;/*!< SPI Control register 1 (not used in I2S mode), Address offset: 0x00 */
4
__IOuint32_tCR2;/*!< SPI Control register 2, Address offset: 0x04 */
5
__IOuint32_tSR;/*!< SPI Status register, Address offset: 0x08 */
6
__IOuint32_tDR;/*!< SPI data register, Address offset: 0x0C */
7
__IOuint32_tCRCPR;/*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */
8
__IOuint32_tRXCRCR;/*!< SPI Rx CRC register (not used in I2S mode), Address offset: 0x14 */
9
__IOuint32_tTXCRCR;/*!< SPI Tx CRC register (not used in I2S mode), Address offset: 0x18 */
Ich bin hier etwas überfragt, da ich ehrlich zugeben muß,
daß ich so was bei mir bisher noch nicht genutzt habe.
Ich bin kein Profi.
Was hat es für einen Vorteil, über einen Zeiger auf SPI_TypeDef zu
gehen?
Ich spreche die Register direkt an.
Außerdem mußt Du ja die SPI2 ansprechen (SPI2_CR1).
Wie hast Du das gelöst?
Jogibär
Aufruf;
spiConfig(SPI2, 5);
Vorteil ist, dass ich den gleichen Code bei jeder SPI-Einheit verwenden
kann, wenn ich die SPI-Einheiten in gleicher Weise nutze (hier z.B. ohne
DMA und ohne Interrupt).
(weiter oben hätte es natürlich ~04UL und Konzentration stehen sollen
;-)
Vor allem ist es flexibler - so hab' ich letzthin einfach den Timer
ausgetauscht, der mein ADC-Engine antreibt und eine Timer verwendet,
dessen Output auf einen Pin gelegt werden kann, um so Messungen mit dem
Oszi machen zu können.
Das dritte Bild zeigt dann gleich auch, wie ich die SPI-IOs konfiguriert
habe.
Statt
SET_BIT(pSpi->CR1, (1 << SPI_CR1_SPE_Pos));
einfach
pSpi->CR1 |= SPI_CR1_SPE;
zu verwenden, ändert am Verhalten nichts.
Ich kann aber unmittelbar nach dem Einschalten der SPI-Clock das SPE-Bit
mit
SET_BIT(pSpi->CR1, (1 << SPI_CR1_SPE_Pos));
tatsächlich setzen!!!
Wenn ich dagegen erst das CR2-Register beschreibe und dann die
Konfiguration von CR1 und das Einschalten des SPI-Devices mittels einer
einzigen Instruktion durchführe,
pSpi->CR1 = SPI_CR1_SPE | (val << SPI_CR1_BR_Pos) | SPI_CR1_MSTR;
landet im CR1-Register letztlich wieder der Wert 0x28!
Das mit dem MODF-Bit ist mal interessant!!!
Zum einen hab' ich gleich mal entdeckt, dass ich
GPIOB->ODR = 0x18000000UL;
statt
GPIOB->ODR = 0x00001800UL;
geschrieben habe und der Pin deshalb tatsächlich auf "0" gezogen wurde.
Aber auch nach Korrektur ändert sich nichts.
Vor Ausführung von Zeile 63 steht im CR1 Register 0x2C und das MODF-Bit
ist nicht gesetzt, nach Ausführung von Zeile 63 habe ich wieder 0c28 im
CR1-register stehen, aber es ist auch tatsächlich das MODF-Bit gesetzt.
Ich verstehe wohl irgendwas bezüglich der Bits SSM, SSI, NSSP und SSOE
noch nicht?
Da ich Master sein möchte, habe ich SSM und SSI auf "0" konfiguriert, da
ich meine Chip-Selects "zu Fuss" mit GPIOs mache, habe ich NSSP und SSOE
auf "0" konfiguriert!?
Uli N. schrieb:> Ich verstehe wohl irgendwas bezüglich der Bits SSM, SSI, NSSP und SSOE> noch nicht?>> Da ich Master sein möchte, habe ich SSM und SSI auf "0" konfiguriert, da> ich meine Chip-Selects "zu Fuss" mit GPIOs mache, habe ich NSSP und SSOE> auf "0" konfiguriert!?
Den Abschnitt "39.5.5 Slave select (NSS) pin management" verstehe ich
so, dass für deine Anwendung 2 Varianten funktionieren sollten:
entweder
a) SSM = 0, SSI = 0, SSOE = 1;
oder
b) SSM = 1, SSI = 1, SSOE = 0;
NSSP sollte in beiden Fällen egal sein (egal mit 51% für NSSP = 1)
a) wegen
1
Bit 2 SSOE: SS output enable
2
0: SS output is disabled in master mode and the SPI interface
3
can work in multimaster configuration
4
1: SS output is enabled in master mode and when the SPI interface
5
is enabled. The SPI interface cannot work in a multimaster
6
environment.
b) wegen
1
Bit 8 SSI: Internal slave select
2
This bit has an effect only when the SSM bit is set. The value of
3
this bit is forced onto the NSS pin and the I/O value of the NSS
4
pin is ignored.
STM scheint den Begriff "Pin" nicht so genau zu nehmen, ich finde b)
ergibt mehr Sinn, wenn hier mit Pin der interne Eingang des SPI-Moduls
gemeint ist. Verwirrung kommt auch daher, dass in einem
Multimastersystem ein Master jederzeit Slave werden kann.
Hab' nun Variante b implementiert, weil auch ich finde, dass b) mehr
Sinn ergibt - und es funktioniert damit.
Allerdings kann ich nicht, wie vermutet, auf einen Schlag 48 Bits
versenden, bei 32 Bits ist Schluss - hatte eigentlich damit gerechnet,
dass ich, wenn ich in CR2 FRXTH=0 und DS=15 wähle, auf SPI2->DR direkt
hintereinander drei 16bit-Worte schreiben kann, weil das erste gleich
ins Schieberegister wandert - dem ist aber nicht so (vermutlich ist das
Schieberegister nur 8bit breit)!
Uli N. schrieb:> weil das erste gleich ins Schieberegister wandert
Vielleicht bist du auch nur zu schnell, wenn nämlich der Takt für das
"gleich wandern" der SPI-Takt ist und nicht der APB-Takt. Je nachdem,
wie das Verhältnis der Taktfrequenzen ist, sind das nur ganz wenige
Zyklen, aber solange muss man irgendwie warten.
lassen sich 6 Bytes raushauen, ohne lange warten zu müssen - cnt wird,
soweit zu sehen, maximal bis auf 3 inkrementiert. Etwas schade ist, dass
schon unmittelbar nach dem Eintreffen des 48 Bits das OVR Bit gesetzt
wird und nicht erst beim Eintreffen des 49 Bits, so dass die beiden
letzten Bytes in diesem Fall leider nicht gelesen werden können.
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang