Forum: Mikrocontroller und Digitale Elektronik ARM STM32G071 - SPI Modus auch 8 Bit möglich


von Michael J. (jogibaer)


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

von Wastl (hartundweichware)


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.

von Wastl (hartundweichware)


Lesenswert?

Wastl schrieb:
> Lies das Datenblatt, da steht alles drin.

.... oder verwende CubeMX, damit kannst du alles vollständig
konfigurieren.

von Michael J. (jogibaer)


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

von Wastl (hartundweichware)


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 ....

von Andreas B. (abm)


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 ...

von Gerhard O. (gerhard_)


Lesenswert?

Wenn ich mich recht erinnere, gibt es dann allerdings im 8-bit Modus 
Pausen. Da sind dann immer 8-bit äquivalente lange Pausen zwischen den 
gesendeten Bytes. Zumindest war das damals bei den F407 und F103 Typen 
so.

von Wastl (hartundweichware)


Lesenswert?

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.

von Gerhard O. (gerhard_)


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.

von Wastl (hartundweichware)


Lesenswert?

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.

siehe
Beitrag "Re: [STM32F4xx] SPI Optimierung"

von Wastl (hartundweichware)


Lesenswert?

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.

von Gerhard O. (gerhard_)


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.

von Wastl (hartundweichware)


Lesenswert?

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.

von Gerhard O. (gerhard_)


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.

von Gerhard O. (gerhard_)


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.

: Bearbeitet durch User
von Harry L. (mysth)


Lesenswert?

Wenn man die HAL nutzt, kann man problemlos 8bit-Werte ohne Pausen 
übertragen.

Aber, HAL ist ja sooo böse...

von Andreas B. (abm)


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 ...

von Gerhard O. (gerhard_)


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

: Bearbeitet durch User
von Andreas B. (abm)


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).

: Bearbeitet durch User
von Andreas B. (abm)


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.

von Gerhard O. (gerhard_)


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

von Gerhard O. (gerhard_)


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.


...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.