ARM STM32G071 - SPI Modus auch 8 Bit möglich

OP #7640020
Lesenswert?

Hallo,

ich habe ein kleineres Problem wie oben beschrieben.

Wenn ich per SPI Daten ausgeben möchte, dann wird immer ein 16 Bit Takt mit ausgegeben, obwohl ich nur 8 Bit Daten konfiguriert habe.

1
pSPI->CR2 |=  (SPI_CR2_ERRIE | SPI_CR2_RXNEIE /*| SPI_CR2_TXEIE */ | SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2 | SPI_CR2_FRXTH);
2

3
pSPI->CR2 &= ~(SPI_CR2_DS_3);

Heißt dies, daß ich eigentlich keine 8 Bit Daten mit 8 Takten ausgeben kann sondern alles auf 16 Bit umändern muß? Oder muß ich etwas anders konfigurieren?

Danke Jogibär

#7640031
Lesenswert?

Michael J. schrieb:

Heißt dies, daß ich eigentlich keine 8 Bit Daten mit 8 Takten ausgeben kann sondern alles auf 16 Bit umändern muß?

Nein.

Michael J. schrieb:

Oder muß ich etwas anders konfigurieren?

Sicher doch. Lies das Datenblatt, da steht alles drin.

Wenn du es nicht schaffst zeige ein komplettes Minimalbeispiel das man nachvollziehen kann. Mit deinen zwei Zeilen Code kann man gar nichts.

OP #7640065
Lesenswert?

Hallo,

folgendes zur Info: https://community.st.com/t5/stm32-mcus-products/spi-8bit-data-length/td-p/423766

Das DR Register ist 16 Bit breit, daher die 16 Clocks. Man kann das aber umgehen, wenn man das DR Register nur mit 8 Bit anspricht. Dann bekomme ich auch nur 8 Clocks. (Siehe meinen Link)

Dann sieht der Code so aus:

1
unsigned char SPI_IRQ_WriteHandler (SPI_TypeDef* pSPI)
2
(pSPI ist dann z.B. SPI1)
3
 {
4
 ...
5
 *(__IO uint8_t *)& pSPI->DR =  ... (Daten)
6
 ...
7
 }

zu __IO habe ich folgendes gefunden: https://stackoverflow.com/questions/51337059/what-is-the-use-of-io-static-keywords-in-c

Jogibär

#7640070
Lesenswert?

Michael J. schrieb:

Man kann das aber umgehen, wenn man das DR Register nur mit 8 Bit anspricht. Dann bekomme ich auch nur 8 Clocks.

Mann kann deinen ganzen Ärger umgehen indem man die offiziellen Makros aus dem STM-Headers (in diesem Fall <stm32g0xx_ll_spi.h> benutzt. Hier im Speziellen

1
__STATIC_INLINE void LL_SPI_TransmitData8(SPI_TypeDef *SPIx, uint8_t TxData)

Heute noch mit einzelnen Bit-Definitionen zu arbeiten ist sehr fehleranfällig.

Wozu du ein SPI Transmit über einen IRQ Handler machst ist mir auch schleierhaft ....

#7640087
Lesenswert?

Michael J. schrieb:

Das DR Register ist 16 Bit breit, daher die 16 Clocks. Man kann das aber umgehen, wenn man das DR Register nur mit 8 Bit anspricht. Dann bekomme ich auch nur 8 Clocks.

Genau, das steht ausdrücklich im RM: "When the SPIx_DR register is accessed, data frames are always right-aligned into either a byte (if the data fits into a byte) or a half-word (see Figure 363). During communication, only bits within the data frame are clocked and transferred."

Halfword-Zugriff bedeutet bei frame size <= 8 Bits, dass halt zwei frames im FIFO landen, bei frame size 9 Bits aber nur einer. Ist aber eigentlich toll, wenn man den FIFO voll machen möchte, geht das u. U. mit jeweils zwei "Häppchen" auf einmal ...

#7640149
Lesenswert?

Wastl schrieb:

Gerhard O. schrieb:

gibt es dann allerdings im 8-bit Modus Pausen.

Das kommt aber sehr darauf an was du mit "dann" meinst. Der Kontext dazu ist nicht eindeutig erkennbar.

Ein Transfer dauert bei ansonsten gleichen Einstellungen genauso lang wie ein 16-bit Transfer. Das kann man am Oszi bestätigen. Zwischen den 8 Takt Impulsen ist dann eine genauso lange "Sendepause". Wenn es also Protokollmässig akzeptabel ist, zwei Bytes in ein 16-bit Word zu verpacken ohne CS dazwischen toggeln zu müssen, ginge das schneller. Mit anderen Worten, der "Throughput" ist im 8-bit Modus nur 50% im Vergleich zu 16-bit.

#7640159
Lesenswert?

Wastl schrieb:

Gerhard O. schrieb:

Wenn ich mich recht erinnere, gibt es dann allerdings im 8-bit Modus Pausen.

Vermutlich nur wenn man sich blöd anstellt. Wenn man es richtig macht kann man praktisch beliebig viele Bytes am Stück senden ohne "Lücken" dazwischen zu haben.

Wie ist das ("blöd") gemeint? Nun, es ist schon lange her. Aber wenn man mit den SFRs den Modus auf 8-bit einstellt, dann ist es eben so. Ob da noch eine Einstellmöglichkeit vorhanden ist, die Pausen zu eliminieren, hat mich damals beim F103 nicht interessiert, weil es für das Firmenprojekt belanglos war, und ich mir darüber weiter nicht den Kopf zerbrach. Ich kann mich auch nicht erinnern, ob da eine SFR Einstellmöglichkeit dafür überhaupt vorhanden war. Jedenfalls fiel es mir im User Manual nicht auf. Auch verwendete ich damals die ST SPL und nicht HAL. War so um 2012 herum.

Schön, zu wissen, daß es vielleicht also trotzdem möglich ist.

siehe Beitrag "Re: [STM32F4xx] SPI Optimierung"

Werde es mir näher ansehen. Danke.

#7640165
Lesenswert?

Wastl schrieb:

Gerhard O. schrieb:

Ein Transfer dauert bei ansonsten gleichen Einstellungen genauso lang wie ein 16-bit Transfer.

Nö. Du unterlässt es hartnäckig die realen Umgebungsbedingungen zu nennen. Also den vorher so genannten Kontext.

Ist zu lange her. Abgesehen davon, habe ich momentan keinen Zugriff auf das alte Projekt. Du verlangst jetzt mich an Details vor über 12 Jahren zu erinnern. Das hat nichts mit Hartnäckigkeit zu tun.

Ist ja gut zu wissen, daß man die Lücke vermeiden kann und das genügt mir im Moment. In der User Manual Register Dokumentation stand damals diese Möglichkeit nicht sehr augenfallend drin, wenn damals überhaupt, sonst hätte ich es entsprechend konfiguriert. Abgesehen war der Projektdruck entscheidender und die PL gab sich wegen der niedrigen Priorität damit zufrieden.

Kontext? Irgendein relativ selten benutztes und relativ unwichtiges SPI Device. Wie gesagt, es war nicht sehr wichtig. Es gab da wichtigere Details zu implementieren. Für ein paar sporadische Zugriffe lohnte es sich damals nicht, da viel Zeit zu investieren. Es bestand einfach kein Grund, da tiefer hineinzutauchen. Diese Eigenschaft wurde einfach konstatiert.

Sollte ich wieder die Notwendigkeit haben, es in der Zukunft optimieren zu müssen, werde ich mich dankend an Deinen Hinweis erinnern.

#7640176
Lesenswert?

Wastl schrieb:

Gerhard O. schrieb:

Ich kann mich auch nicht erinnern, ob da eine SFR Einstellmöglichkeit dafür überhaupt vorhanden war.

So ein Käse. Natürlich gibt es keine "Einstellmöglichkeit" mit der Option "Null Pause zwischen den SPI Bytes". Es ist einfache Programmiertechnik mit den Registern die diese Nullpausen ermöglicht.

Ist dies allgemein bekannt? Ich hatte mich damals erstmalig nur kurze Zeit mit dem STM32 eingearbeitet und hatte ein Projekt mit einer fixen Deadline durchzuziehen. Zweitens, bestand keine zwingende Notwendigkeit die Lücke unbedingt zu vermeiden. Drittens, wie hätte ein "Anfänger" darauf kommen sollen, daß es eine Lösung dafür gab. Oder stand dies sogar in einer mir unbekannten Appnote?

Wie bist Du denn darauf gekommen, daß es mit einer speziellen Programmiertechnik überhaupt möglich ist, diese Eigenschaft zu vermeiden? Ich meine, so selbstverständlich ist das nun wieder auch nicht, wenn man mit der relativ oberflächlichen Hersteller HW Doku arbeiten muß. Da ist dann halt das User Manual ausschlaggebend. Die ST Doku behandelte ziemlich viele Peripherie Details ziemlich stiefmütterlich so dass man nicht unbedingt sofort Ausweichmöglichkeiten erkennt. Nicht jeder ist ein Programmier-Zauberer oder Genie. Es gibt auch noch mittelmäßige "Gelegenheits" Programmierer in der Welt.

Wie gesagt, ich habe mich schon 12J nicht mehr damit befasst und arbeite nicht die ganze Zeit damit.

#7640338
Lesenswert?

Gerhard O. schrieb:

So ein Käse. Natürlich gibt es keine "Einstellmöglichkeit" mit der Option "Null Pause zwischen den SPI Bytes". Es ist einfache Programmiertechnik mit den Registern die diese Nullpausen ermöglicht.

Eben, diese nennt sich "FIFO verwenden", s. 35.5.9: All SPI data transactions pass through the 32-bit embedded FIFOs. This enables the SPI to work in a continuous flow, and prevents overruns when the data frame size is short. ... A few data frames can be passed at single sequence to complete a message. When transmission is enabled, a sequence begins and continues while any data is present in the TXFIFO of the master. The clock signal is provided continuously by the master until TXFIFO becomes empty, then it stops waiting for additional data."

Keine Magie oder so ...

#7640503
Lesenswert?

Andreas B. schrieb:

Gerhard O. schrieb:

So ein Käse. Natürlich gibt es keine "Einstellmöglichkeit" mit der Option "Null Pause zwischen den SPI Bytes". Es ist einfache Programmiertechnik mit den Registern die diese Nullpausen ermöglicht.

Eben, diese nennt sich "FIFO verwenden", s. 35.5.9: All SPI data transactions pass through the 32-bit embedded FIFOs. This enables the SPI to work in a continuous flow, and prevents overruns when the data frame size is short. ... A few data frames can be passed at single sequence to complete a message. When transmission is enabled, a sequence begins and continues while any data is present in the TXFIFO of the master. The clock signal is provided continuously by the master until TXFIFO becomes empty, then it stops waiting for additional data."

Keine Magie oder so ...

Hallo Andreas,

Danke für Deine Hinweise.

Auf welches Reference Manual bezieht sich die Seiten Information? Ich habe mal schnell das 1100 seitige F103 RM konsultiert (RM0008 R21) und das geht nur bis Sektion 31. beim F103 ist das aber S25. Der scheint dem Blockschaltbild nach aber kein SPI FIFO zu haben (Oder bin ich blind?). In der 25.2.2 Feature List, steht nichts davon. DMA wäre zwar schon möglich gewesen, aber da ich damals noch blutiger STM32 Anfänger mit nur ein paar Wochen vorheriger Einarbeitung war, erschien mir DMA mit dem externen ADC Wandler doch etwas Overkill. Abgesehen davon, mußte EOC regelmäßig erfasst werden. Den internen 12-bit ADC habe ich allerdings schon erfolgreich mit DMA und ISR eingestellt gehabt.

Ich arbeitete damals mit dem F103VET an einem Modbus Sensor Projekt. Der SPI war mit einem externen 24-bit ADC verbunden. Wenn ich mich recht erinnere, gab es nur ein ADC Setup nachdem Einschalten und dann warten auf regelmäßige EOC Transitionen am MISO-Pin, die durch einen externen Pin-Interrupt detektiert wurden, um die neuen ADC Daten Pakete abzuholen. Ich weiß nicht ob sich da die FIFO Methode gelohnt hätte, auch wenn sie es gegeben hätte. Der ADC produzierte ja theoretisch maximal nur einige hundert Konvertierungen per s. Nach dem Setup bestimmte also der ADC die Häufigkeit und Konvertierungsrate. Das konnten bestenfalls 900 Konvertierungen/s sein. Bei den jeweilig drei Bytes Einlesen alle 10ms scheint scheint es in meinen Augen ohnehin kein DMA Fall zusein. Da genügte auch die ISR.

Die Frage wäre also, ob DMA alternativ auch gut gearbeitet hätte und wie das mit EOC dann überhaupt funktioniert hätte, dass ja extern detektiert werden musste und nicht SPI konform am MISO Pin vom ADC signalisiert wurde. Irgendwie kann ich dies nicht leicht in Einklang bringen, weil der F103 auch der SPI Master sein mußte. Der ADC war übrigens ein MAX11200, wenn ich mich recht erinnere. Sollte vollautomatischer DMA Betrieb mit dem ADC tatsächlich möglich sein, würde mich das schon sehr interessieren. Wie hätte man der DMA überhaupt das MISO EOC signalisieren können, damit es als SPI Master die Daten automatisch eingelesen hätte? Das erschliesst sich mir nicht wirklich.

Funktioniert hat es ja auch zuverlässig und gut. Nur hätte man es vielleicht eleganter verwirklichen können. Abgesehen davon war das nur ein kleiner Teil des Designs und Modbus und andere SW Notwendigkeiten erforderte ohnehin viel mehr Aufmerksamkeit. Die angewendete Methode funktionierte auch so ohnehin vollkommen im Hintergrund.

Nach diesen Projekt machte ich dann nur noch etwas privat Sachen mit dem F103 bzw. Dem F407. Da kam das nie wieder auf.

Jedenfalls danke ich Dir, auf den Einwand zum nachträglichen Überlegen. Jetzt kennst Du etwas den Kontext.

Gruß, Gerhard

#7640530
Lesenswert?

Gerhard O. schrieb:

Auf welches Reference Manual bezieht sich die Seiten Information? Ich habe mal schnell das 1100 seitige F103 RM konsultiert (RM0008 R21) und das geht nur bis Sektion 31. beim F103 ist das aber S25. Der scheint dem Blockschaltbild nach aber kein SPI FIFO zu haben (Oder bin ich blind?).

Da es lt. Überschrift um STM32G071 ging, natürlich um dessen RM0444. Klar kann dass bei anderen Derivaten total anders sein, bisweilen gibt es sogar in einem(!) verschiedene Versionen der Peripherie. Also z. B. bei G031 u. A. ein "full featured" USART und ein "basic" (und beide unterscheiden sich zufälligerweise gerade im (Nicht-)Vorhandensein eines FIFOs).

#7640540
Lesenswert?

Ach ja, der F407 hat genau genommen auch ein FIFO, auch wenn der im RM nicht so genannt wird: "Tx buffer". Denn da kann schon der nächste frame rein, obwohl der vorherige (im Shift register) noch im Herausschieben begriffen ist. Nur sagt man zu einem FIFO der Tiefe 1 halt üblicherweise "buffer", aber Namen sind ja nur Schall und Rauch ...

"When transmitting data in master mode, if the software is fast enough to detect each rising edge of TXE (or TXE interrupt) and to immediately write to the SPI_DR register before the ongoing data transfer is complete, the communication is said to be continuous. In this case, there is no discontinuity in the generation of the SPI clock between each data item and the BSY bit is never cleared between each data transfer."

Bei Tiefe 1 muss man halt immer schnell genug nachschieben, während beim tieferen FIFO etwas mehr "Luft" ist, wenn man den immer gleich randvoll macht.

Beim F103 hab' ich nicht nachgeschaut, aber da der F407 nur wenig jünger ist, dürfte es da ähnlich sein.

#7640681
Lesenswert?

Moin,

Naja, bei mir ging es dann während dieser Austausche hier um den F103. Also nicht unbedingt Thema gerecht.

Aber wie hättet denn ihr den MAX11200 mit der SW implementiert? Die SPI Transaktionen müssen ja, ungleich Verbindung mit einem anderen ähnlichen Gerät, Chip spezifisch berücksichtigt werden. Beim internen ADC war das der Fall. Ich glaube nicht, dass ich es damals soo "schlecht" gemacht habe in Anbetracht der Tatsache, daß der STM32 für mich vollkommen neu war. Immerhin wurden da die ADC Resultate im Hintergrund abgearbeitet und blockierten den Prozessor nicht mehr als nötig. Wegen drei Bytes alle 10ms fällt die MCU Welt auch nicht aus den Angeln. Aber die Lücken zwischen den Bytes mußte ich in Kauf nehmen. Als Sklave war der MAX11200 auch total vom Master für die Abwicklung abhängig.

Die DMA mit dem internen ADC ist ja eng mit der ADC HW verknüpft und da funktionierte DMA Xfr. sehr bequem für mich. Nur beim MAX11200 wußte ich es nicht wie das überhaupt zu bewerkstelligen sei. Da war das ausschlaggebend, da ja genug andere Arbeit mit dem Rest des SW Designs anfiel. Und ja, ich vollendete das Design on Time und es hat sich verkaufsmäßig gut bewährt.

Gerhard

#7640685
Lesenswert?

Andreas B. schrieb:

Ach ja, der F407 hat genau genommen auch ein FIFO, auch wenn der im RM nicht so genannt wird: "Tx buffer". Denn da kann schon der nächste frame rein, obwohl der vorherige (im Shift register) noch im Herausschieben begriffen ist. Nur sagt man zu einem FIFO der Tiefe 1 halt üblicherweise "buffer", aber Namen sind ja nur Schall und Rauch ...

"When transmitting data in master mode, if the software is fast enough to detect each rising edge of TXE (or TXE interrupt) and to immediately write to the SPI_DR register before the ongoing data transfer is complete, the communication is said to be continuous. In this case, there is no discontinuity in the generation of the SPI clock between each data item and the BSY bit is never cleared between each data transfer."

Bei Tiefe 1 muss man halt immer schnell genug nachschieben, während beim tieferen FIFO etwas mehr "Luft" ist, wenn man den immer gleich randvoll macht.

Beim F103 hab' ich nicht nachgeschaut, aber da der F407 nur wenig jünger ist, dürfte es da ähnlich sein.

Das alles trifft auf den F103 ohnehin nicht zu. Der hat nur einen einfachen Datenpuffer und man muß sich die Daten sofort abholen.

...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren