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 ?
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.
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 ?
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 :-)
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.
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 ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.