Forum: Mikrocontroller und Digitale Elektronik Problem mit STM32 CubeMX I2S DMA


von Rene B. (themason) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo liebe Leuts ....

ich habe mal wieder ne Ecke an der ich momentan etwas hänge und nicht so 
recht weiß warum ...
Ich habe ein STM32F407 Board welches ich mit System Workbench for STM32 
und CubeMX programmiere.
Ich möchte I2S (erstmal nur TX) nutzen und auf einem Audio DAC per DMA 
ausgeben. Die Konfiguration von CubeMX passt soweit, Clocks passen, 
Daten kommen raus und Audio ist auf dem Wandler auch zu hören.
Ich benutze einen PCM5102A DAC, da ich bei dem keinen Master Clock 
benötige.
Ich gebe fürs erste einfach nur mal nen Sinus aus den ich auf beiden 
Kanälen hören möchte.
Es kommt auch auf dem einen Kanal ein Sinus raus. Auf dem anderen zwar 
auch, aber da sind Spikes zu sehen. Die Spikes treten (hab ich mit nem 
Scope gemessen) immer entsprechend der Blocklänge auf (also in dem Falle 
alle 64 Samples * 48kHz = 1,32ms).
Was mich etwas stutzig macht ist das nur der eine Kanal betroffen ist. 
Der andere klingt (und ist aufm Scope) sauber.
Ich verwende den Circular DMA Buffer. Ich habe 2 Buffer angelegt und bei 
jedem DMA Transfer schalte ich zwischen den Buffern um, sodass während 
der eine Wiedergegeben wird, der andere befüllt wird.
Ich habe mal das Projekt als Export angehängt. Die Umschaltung der 
Buffer findet in der Datei audio_buffer.c statt und wird von 
"HAL_I2S_TxCpltCallback" aufgerufen.
Hat irgendjemand vllt ne Idee warum das letzte Sample immer "falsch" ist 
und warum nur auf einem Kanal, und (die Gretchenfrage) was ich dagegen 
machen kann ?

von Martin B. (ratazong)


Lesenswert?

Du benutzt ja den HAL_I2S_TxHalfCompleteCallback() des Circular DMA gar 
nicht. Warum?

Im Circular Mode gibt es zwei Callbacks. Der Halfcomplete kommt, wenn 
die erste Hälfte des DMA Buffers gesendet wurde. Dann kannst Du die 
erste Hälfte neu füllen. Wenn der Complete kommt kannst Du die zweite 
Hälfte füllen u.s.w.

Du füllst den kompletten Buffer der DMA nach dem Complete Callback. Der 
Complete Callback muss jetzt allerschnellstens die untere Hälfte des DMA 
Buffers füllen, denn die circular DMA arbeitet ja schon in dem Bereich.

Wenn bei Dir nur ein Kanal betroffen ist, müsste es der rechte sein.

von Rene B. (themason) Benutzerseite


Lesenswert?

Ah oki ...
Also die beiden Callbacks sind quasi für 50% und 100% des Buffers 
übertragen gedacht ? Das war mir nicht ganz klar.
Ich hatte das irgendwie mit Full und Halfduplex verwechselt ... aber so 
im Nachhinein ist das natürlich Quäse.

Also demnach müsste ich bei TxHalf die erste Hälfte des Buffers befüllen 
(weil diese gerade übertragen worden ist und nun die zweite hälfte 
angefangen wird), und bei TxCplt die zweite Hälfte (weil diese gerade 
übertragen worden ist und der Buffer wieder mit der ersten Hälfte 
anfängt) befüllen ?

von Bülent C. (mirki)


Lesenswert?

Wähle einen möglichst kleinen dma buffer

von Rene B. (themason) Benutzerseite


Lesenswert?

Bülent ... schon klar ;-)

Ich wollte erstmal mit 64 Samples anfangen. Später werden es dann sicher 
32 Samples werden. Sollte für nen Synthie ausreichend sein :-)

von Martin B. (ratazong)


Lesenswert?

Rene B. schrieb:
> Ah oki ...
> Also die beiden Callbacks sind quasi für 50% und 100% des Buffers
> übertragen gedacht ? Das war mir nicht ganz klar.
> Ich hatte das irgendwie mit Full und Halfduplex verwechselt ... aber so
> im Nachhinein ist das natürlich Quäse.
>
> Also demnach müsste ich bei TxHalf die erste Hälfte des Buffers befüllen
> (weil diese gerade übertragen worden ist und nun die zweite hälfte
> angefangen wird), und bei TxCplt die zweite Hälfte (weil diese gerade
> übertragen worden ist und der Buffer wieder mit der ersten Hälfte
> anfängt) befüllen ?

Ja genau.
Und wenn Du es richtig schnell haben willst musst Du von CubeMX runter, 
sonst ist mit kleinen Buffern nichts. Da ist zu viel overhead drin.

von Rene B. (themason) Benutzerseite


Lesenswert?

Na ja ... ich würde später CubeMX als "Rahmen" nutzen und mich dann 
direkt an die Interrupts hängen. Die Initialisierung ist ja schon recht 
schick gelöst. Aber ich denke fürs erste reicht das erstmal.

Ich setz deinen Tipp mal um. Erstmal vielen Dank.
Wenn ich fragen hab nerv ich euch wieder ;-)

von Rene B. (themason) Benutzerseite


Lesenswert?

Ok ...

Habs mal umgesetzt und nu funzt es. Vielen Dank nochmal.

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.