Problem mit STM32 CubeMX I2S DMA

OP Persönliche Seite #5304267
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:
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
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 ?
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.
OP Persönliche Seite
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 ;-)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.