Problem mit STM32 CubeMX I2S DMA

OP Persönliche Seite #5304267
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 ?
Angehängte Dateien:
#5304303
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.
OP Persönliche Seite #5304311
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 ?
#5304337
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.

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