Forum: Mikrocontroller und Digitale Elektronik STM32f407 (black) SDIO CLK Fragen


von Paul G. (paul_g210) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hi

Ich habe mal ein paar Fragen zu SDIO und dem STM32F407VET, verbaut auf 
den billig Teil (black board).

Erstmal eine Sache die mich irritiert. Wenn ich folgende Clock Config 
verwende (CubeIDE):
HSE=8MHz
PLL=HSE
HCLK=168MHz

und ich habe als "48MHz clocks" 48MHz und SDIOCLK divide ist 0,dann 
messe ich mit meinem Oszilloskop 42MHz, direkt am MicroSD-Card-Slot am 
SDIO_CK PIN.

Warum lese ich dort nicht 48MHz?

Wenn ich nun SDIOCLK_DIV auf 10 stelle würde ich erwarten 48/10=4,8MHz, 
aber ich bekomme nun exakt 7MHz. Warum ist das so?

Frage zum Datenblatt und der Aussage:

"PCLK2 and SDIO_CK clock frequencies must respect the following 
condition:
Frequency ( PCLK2 ) ≥ 3 ⁄ 8 × Frequency ( SDIO_CK )"

Verstehe ich richtig das wenn ich SDIO_CK=48MHz hätte, PCLK2 mindestens 
oder mehr als 0,375*48MHz=18MHz haben muss?

Ich habe folgendes gelesen:
"Die SDIO-Peripherie hat einen Bug und kann nur 33MHz"
(Beitrag "Re: Hilfe bei stm32 Wahl")

Gibt es dazu irgendwo nähere Informationen?

: Bearbeitet durch User
von A. B. (Gast)


Lesenswert?

Wohl deshalb, weil die 48 MHz tatsächlich 84 Mhz sind?!

CLKDIV = 0 heißt geteilt durch 2, CLKDIR = 10 heißt geteilt durch 12.
42 MHz * 2 = 84 MHz, 7 MHz * 12 = 84 MHz,
und nach Reset ist PLLQ "rein zufällig" auf geteilt durch vier 
eingestellt,
so dass die "angeblichen" 48 MHz halt 84 MHz sind ...

Der 48 MHz Clk heißt nicht so, weil da automatisch 48 MHz herauskommen, 
sondern weil er so eingestellt werden SOLL, dass sich 48 MHz ergeben 
(nur dann kann man USB benutzen).

Im Zweifel schaut man in den PLL-Registern mal nach und rechnet anhand 
des RM mit Papier und Bleistift aus, ob dass auch so funktioniert, wie 
man es gern hätte.

von Johannes S. (Gast)


Lesenswert?


von Paul G. (paul_g210) Benutzerseite


Angehängte Dateien:

Lesenswert?

A. B. schrieb:

> CLKDIV = 0 heißt geteilt durch 2, CLKDIR = 10 heißt geteilt durch 12.


Okay, das habe ich im Reference Manual total übersehen:
1
Bits 7:0 CLKDIV: Clock divide factor This field defines the divide factor between the input clock (SDIOCLK) and the output clock 
2
3
(SDIO_CK): SDIO_CK frequency = SDIOCLK / [CLKDIV + 2].

Aber wo genau kommt dann SDIOCLK her? Ist das PCLK2?

Und dann kann ich den ganzen "48MHz Zweig" in CubeIDE eigentlich 
ignorieren und mein SDIO_CK aus CLKDIV und SDIOCLK generieren?

Johannes S. schrieb:
> Hier ist das Errata, mit den 48 MHz kann es auch Probleme geben:
> 
https://www.st.com/resource/en/errata_sheet/dm00037591-stm32f405-407xx-and-stm32f415-417xx-device-limitations-stmicroelectronics.pdf#page35

Das betrifft mich doch eigentlich nur wenn ich das "BYPASS" Bit gesetzt 
und NEGEDGE auf 0 steht.

von A. B. (Gast)


Lesenswert?

Paul G. schrieb:
> Aber wo genau kommt dann SDIOCLK her? Ist das PCLK2?

Nein, der CLK48 ist ein separater Ausgang der Main-PLL mit dem 
Teilerfaktor PLLQ, während der Rest (HCLK etc.) über den Teiler PLLP 
gewonnen wird, beschrieben unter 7.3.2 RCC_PLLCFGR.

von pegel (Gast)


Angehängte Dateien:

Lesenswert?

DB Seite 19.

von Paul G. (paul_g210) Benutzerseite


Lesenswert?

A. B. schrieb:
> Nein, der CLK48 ist ein separater Ausgang der Main-PLL mit dem
> Teilerfaktor PLLQ, während der Rest (HCLK etc.) über den Teiler PLLP
> gewonnen wird, beschrieben unter 7.3.2 RCC_PLLCFGR.

Ah, okay. Jetzt verstehe ich auch deine 84MHz von oben. Ich dachte du 
meinst mit  den 84MHz PCLK2, der ist nämlich auch 84MHz wenn HCLK 168MHz 
und APB2 /2 ist...

Aber woher kommt die Abhängigkeit?
1
Frequency ( PCLK2 ) ≥ 3 ⁄ 8 × Frequency ( SDIO_CK )

von A. B. (Gast)


Lesenswert?

Da die Peripherie z. T. nicht mit dem "normalen" Bustakt (AHB, APB) 
betrieben wird, die Register der Peripherie aber schon, müssen zwischen 
den Registern
und der eigentlichen Peripherie Synchronisierstufen geschaltet sein, die 
eine einerseits gewisse Verzögerung bewirken und für die Bussignale eine 
gewisse Mindest-Gültigkeit verlangen, damit alle Signaländerungen am 
Eingang tatsächlich auch am Ausgang ankommen.

von Paul G. (paul_g210) Benutzerseite


Lesenswert?

Okay. Eine Frage noch.

Angenommen ich will die MCU mit HCLK=4MHz laufen lassen (um Energie zu 
sparen), wie berechne ich am besten die Frequenz für mein SDIO_CK?

HSE=8MHz
System Clock Mux = HSE = SYSCLK
HCLK = SYSCLK/2 = 4MHz
PCLK2 = 4MHz
PLL Mux = HSE
/M = 4
*N = 72
/Q = 3

Kann ich SDIO überhaupt betreiben wenn HCLK=4MHz ist?

Ich hätte jetzt erstmal versucht herauszufinden wie groß SDIO_CK max. 
sein darf
wenn PCLK2=4MHz ist, wegen der Formel:
"Frequency ( PCLK2 ) ≥ 3 ⁄ 8 × Frequency ( SDIO_CK )"

Und wenn ich das nicht schon vergeigt habe müsste das ergeben:
PCLK2/(3/8) = 4 MHz / 0.375 = 10.6MHz
SDIO_CK ≤ 10.6MHz

Und jetzt muss ich den CLKDIV+2 so berechnen das ich weniger als 10.6MHz 
raus bekomme?

von A. B. (Gast)


Lesenswert?

Tja, das ist mit den verschiedenen Takten schon etwas kompliziert ...

Generell wäre es aber sinnvoller, nicht den Takt soweit herunter zu 
drehen,
sondern die div. Stop-Modi bzw. Standby-Mode zu nutzen, um den Verbrauch 
zu reduzieren. Bei einem simpel gestrickten Controller ist ein niedriger 
Takt sicher sinnvoll, aber beim F4xx gibt es so viele Möglichkeiten des 
"Aufwachens", das da für jede Anwendung etwas passendes dabei sein 
sollte, RTC, Timer, Interrupt via Pin, ...

Den CLK48 sollte man wenn irgend möglich auch bei 48 MHz lassen, denn 
wenn man später doch mal USB nutzen will, kann man sonst alles über den 
Haufen werfen.

von Paul G. (paul_g210) Benutzerseite


Lesenswert?

A. B. schrieb:
> Generell wäre es aber sinnvoller, nicht den Takt soweit herunter zu
> drehen

Die Erfahrung habe ich nun auch gemacht.

A. B. schrieb:
> sondern die div. Stop-Modi bzw. Standby-Mode zu nutzen, um den Verbrauch
> zu reduzieren.

ich schätze das geht bei meinem Vorhaben nicht. Der STM32F4 soll 
zusammen mit SDIO einen Datenlogger ergeben der so etwa 24h - 36h Daten 
aufzeichnet. Theoretisch brauche ich nur ~25kB/s auf die MicroSD Karte 
zu schreiben, da lag es für mich halt nah zu versuchen den Systemtakt so 
niedrig wie möglich hin zu bekommen soweit bis SDIO noch zuverlässig 
funktioniert.

Inzwischen bin ich bei HCLK=32MHz angekommen und SDIO_CK hat 1,18MHz.
Das scheint zu funktionieren wobei ich die ganze Kommunikation der Daten
noch gar nicht geschrieben habe. Zumindest das Mounten und Schreiben von 
32x32kB großen Blöcken in 2 Sekunden scheint erst mal fehlerfrei zu 
funktionieren. Das würde 512kB/s ergeben und sollte locker ausreichen.

Ich hab diverse andere Systemtakte <32MHz probiert 
24Mhz,16MHz,8MHz,4MHz...
Das Problem war immer SDIO war zum teil nur bereit zu Funktionieren wenn 
ich CLKDIV auf enorm hohe Werte gestellt habe so dass SDIO_CK am Ende 
nur noch < 500kHz war und auch dann nicht immer Fehlerfrei lief.

Im ST-Forum haben es wohl doch ein paar Leute hinbekommen mit niedrigem 
Systemtakt SDIO zu verwenden und ziemlich gute Schreibraten zu bekommen:

https://community.st.com/s/question/0D50X00009XkhDE/sdio-minimum-sysclk-question

Allerding verwenden die richtige Boards (Discovery) wo womöglich das PCB 
Layout auch viel besser ist als auf meinem 15€ STM32F4XX Black Board...

von A. B. (Gast)


Lesenswert?

Niedrigerer Takt sollte eigentlich unkritisch sein ... Wenn es damit 
Probleme gibt, ist es einen Versuch Wert, die Ausgänge "langsamer" zu 
machen, d. h.
OSPEEDR auf "Medium Speed" oder gar "Low Speed". Das ist ja unabhängig 
von den sonstigen GPIO-Einstellungen.

Aber trotzdem frage ich mich, warum das mit den Stop/Standby-Modi nicht 
gehen soll: Gerade beim Loggen will man doch regelmäßig (Timer!) oder 
bei bestimmten Ereignissen (Interrupt!) etwas machen. Da bietet sich das 
"Aufwachen" an.

von Paul G. (paul_g210) Benutzerseite


Lesenswert?

A. B. schrieb:
> Gerade beim Loggen will man doch regelmäßig (Timer!) oder
> bei bestimmten Ereignissen (Interrupt!) etwas machen. Da bietet sich das
> "Aufwachen" an.

Es ist ja nicht so das ich aller 500ms etwas loggen will, ich bekomme 
von einem EKG-IC (ein IN-AMP mit dahinterliegendem ADC sozusagen, 
ADAS1000 ...) durchgängig Daten über SPI mit einer einer Datenrate von 
2000 Frames pro Sekunde (SPI_CLK 500kHz), wobei ein Frame aus 128bit (4 
WORD) besteht. Danach verwerfe ich das erste WORD (den HEADER) und es 
bleiben drei Daten WORDS á 32bit übrig (die drei EKG Elektroden), das 
macht dann meine 24kB/s die ich dann zum schreiben auf SDIO noch in 
einen Buffer schreibe.

Wo ich da Standby oder so verwenden soll erschließt sich mir nicht ganz, 
ich muss beim EKG ja durchgängig Daten abfragen, also in 0,5ms bei 2000 
FPS Abständen.

von Paul G. (paul_g210) Benutzerseite


Lesenswert?

Aber vermutlich ist das garnicht so wild alles... Ich entschließe mich 
vermutlich dazu das ganze System dann mit einer 18650 3000mA zu 
Betreiben.
Selbst bei 24h Dauerbetrieb hätte ich da mehr als 100mA zur Verfügung 
und mein
jetziger Verbrauch mit SDIO schreiben liegt bei ungefähr 50-70mA...

Bevor ich mir unendlich den Kopf darüber zerbreche muss ich sowieso 
erstmal kappieren wie ich die Daten effizient auf die SD-Karte schreibe, 
ob DMA oder nicht... Das wird im Endeffekt das komplizierteste bei 
meinen kognitiven Fähigkeiten :D

von A. B. (Gast)


Lesenswert?

Bei so kurzen Intervallen ist das natürlich schon etwas grenzwertig, 
aber:

SPI und DMA kann man zumindest im Sleep-Mode eingeschaltet lassen, also 
den Controller nur alle paar Sekunden aufwecken, einen großen Block auf 
die SD-Karte schreiben und weiter schlafen ...

von Johannes S. (Gast)


Lesenswert?

bringt eine geringerer SDIO Takt überhaupt eine Ersparnis? Die Energie 
die man braucht ist ja Zeit * Leistung, und wenn ich zwar weniger 
Leistung habe brauche ich dann mehr Zeit um die Daten zu schreiben. Da 
müsste dann etwas effizienter sein damit ich überhaupt etwas spare.
Und wenn die SDC mal etwas länger braucht um etwas zu verarbeiten, dann 
muss eine Zeitüberschreitung wieder aufgeholt werden. Und das geht nur 
wenn ich schneller schreiben kann als die Daten eintrudeln.

von Paul G. (paul_g210) Benutzerseite


Lesenswert?

A. B. schrieb:
> PI und DMA kann man zumindest im Sleep-Mode eingeschaltet lassen, also
> den Controller nur alle paar Sekunden aufwecken, einen großen Block auf
> die SD-Karte schreiben und weiter schlafen ...

Das Problem dabei ist die Daten die vom EKG kommen sind nicht immer 
sinnvolle/gültige Datenpakete. Der Ablauf sieht ungefähr so aus:

--sende 0x40000000 an das EKG um das Framing zu aktivieren
--sende weiter 0x00 (NOP) ans EKG um kontinuierlich Frames zu erhalten
(das könnte man ja via DMA machen)
--wenn empfangender Frame Header 0x80 ist sind die folgenden 3 Words 
gültige Daten.

Manchmal kommt halt drei oder vier Frames lang nur ungültiges Zeug und 
das will ich logischerweise nicht mit loggen. Also muss ich eigentlich 
jedes Frame auf 0x80 prüfen und das geht doch nur als polling oder?

Der EKG hat sogar ein DATA READY Pin der mir signalisieren kann ob 
gültige Daten vorliegen,nur leider kommen auch hier die Daten nicht 
sofort sondern auch davor kann ungültiges Zeug liegen, auch hier muss 
ich auf den 0x80 Header warten...

https://www.mikrocontroller.net/attachment/preview/454163.jpg

von Paul G. (paul_g210) Benutzerseite


Lesenswert?

Johannes S. schrieb:
> bringt eine geringerer SDIO Takt überhaupt eine Ersparnis?

Ich "glaube" nicht, es ging eigentlich nur um den HCLK, die SD-Karte 
ansich
zieht so wie es bei mir aussieht immer um die ~15mA wenn ich schreibe 
unabhängig von SDIO_CK.

von Paul G. (paul_g210) Benutzerseite


Lesenswert?


von A. B. (Gast)


Lesenswert?

Paul G. schrieb:
> A. B. schrieb:
>> PI und DMA kann man zumindest im Sleep-Mode eingeschaltet lassen, also
>> den Controller nur alle paar Sekunden aufwecken, einen großen Block auf
>> die SD-Karte schreiben und weiter schlafen ...
>
> Das Problem dabei ist die Daten die vom EKG kommen sind nicht immer
> sinnvolle/gültige Datenpakete. Der Ablauf sieht ungefähr so aus:
> Manchmal kommt halt drei oder vier Frames lang nur ungültiges Zeug und
> das will ich logischerweise nicht mit loggen. Also muss ich eigentlich
> jedes Frame auf 0x80 prüfen und das geht doch nur als polling oder?

Solange es gültige SPI-Frames sind (also keine fehlenden Bits oder so), 
kann man das doch auch beim "Einpacken" machen. Sprich alles per DMA 
ins RAM, und erst wenn der Buffer fast voll ist (da die doch ziemlich 
regelmäßig kommen, kann man das über einen Timer machen), den Buffer 
einmal ablaufen, die guten in Töpfchen ... Und danach auf die SD-Karte. 
Besonders gut wäre da der "circular mode" bei DMA.

Das setzt allerdings voraus, dass die Pakete "unaufgefordert" kommen, 
muss man jedes einzeln anfordern, wird's deutlich komplizierter. Da 
könnte man per Timer und DMA eine Anforderung per SPI schicken.

Aber unabhängig von der Frage Sleep Mode oder nicht: Es muss ein relativ 
großer Buffer im RAM zur Verfügung stehen: SD-Karten haben die 
unerfreuliche Eigenschaft, dass das Schreiben einzelner Blöcke ziemlich 
unterschiedlich lange dauern kann. Was der Hersteller da allgemein zur 
"Geschwindigkeit" sagt, ist nur ein Mittelwert mit unklaren 
Randbedingungen. Oder man hat eine ganz spezielle Karte, bei der der 
Hersteller tatsächlich eine maximale Dauer bei Schreiboperationen 
garantiert.

von Paul G. (paul_g210) Benutzerseite


Lesenswert?

A. B. schrieb:
> Sprich alles per DMA ins RAM, und erst wenn der Buffer fast voll...

Darauf bin ich garnicht gekommen. Ich probiere das sicher mal aus ob ich 
das hinbekomme.

A. B. schrieb:
> Das setzt allerdings voraus, dass die Pakete "unaufgefordert" kommen

Wie gesagt, ich muss permanent NOPs ans EKG senden damit die Pakete 
raustakten.

A. B. schrieb:
> Es muss ein relativ großer Buffer im RAM zur Verfügung stehen

Naja, der STMF407 ist ja nun nicht gerade riesig mit seinen 192kB RAM 
wobei ich in CubeIde eh nur 128kB sehe und die restlichen 64kB stehen im 
"CCMRAM", was auch immer das sein soll... Aber ich probiere es einfach 
mal ob ich mit einem 64kB großen Puffer schaffe kontinuierlich zu 
schreiben.

von Johannes S. (Gast)


Lesenswert?

Das CCMRAM kann nur von der CPU benutzt werden, der DMA kommt da wimre 
nicht dran.

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.