HAFTUNGSAUSSCHLUSS : Diese Frage hängt irgendwie mit dieser anderen Frage von mir zusammen , aber letztere hatte keine zufriedenstellende Antwort.
Ich arbeite an einem Audio-DSP-Projekt mit dem STM32F4xx und verwende 4 Audioeingänge und 1 Audioausgang .
Ich muss - jeden Eingang lesen - das Signal jedes Eingangs verarbeiten, - die verarbeiteten Signale zusammenmischen - das Ergebnis ausgeben.
Der Eingang wird über einen der 3 internen DACs des STM32 erhalten , 1 Kanal für jeden Eingang (dh 4 Kanäle zum Scannen insgesamt) und unter Verwendung von DMA in einem Puffer gespeichert .
Die Ausgabe wird durch einen Codec unter Verwendung eines I2S-Busses bei 48 kHz konvertiert.
Jedes Mal, wenn der Codec einen Puffer (oder genauer gesagt einen halben Puffer) fertig konvertiert hat, löst er eine Callback-Funktion aus , in der ich derzeit den gesamten DSP-Code habe. In der Schleife werden die Ausgangsabtastwerte berechnet und an den Halbpuffer gesendet, um unter Verwendung von DMA an I2S ausgegeben zu werden.
Angenommen, ich sample meinen Eingang mit der gleichen Rate wie meinen Ausgang (48 kHz, was bedeutet, dass mein DAC mit 4 * 48 kHz = 192 kHz getaktet sein muss), wie kann ich den ADC und die DAC-Konvertierung synchronisieren ?
Ich habe an einen FIFO zwischen dem Eingang und der DSP-Routine gedacht, der jedes Mal, wenn ich einen verarbeiten muss, einen Abtastwert in der Warteschlange auswählt. Aber ich bin mir nicht sicher, wie ich das machen soll, wenn ich mit Datenblöcken arbeite (ein Puffer hat eine Tiefe von 64 Samples).
Eine andere Lösung wäre, eine Eingangspuffertiefe von nur 1 Sample zu haben und dieses Sample in der DSP-Routine zu lesen, aber ich bin mir nicht sicher, ob dies funktionieren würde.
Weiß jemand wie man das am besten macht? Oder noch besser, wie synchronisiert man den ADC des STM32 mit einem externen Codec?
BEARBEITEN : Ich habe auch daran gedacht, den DAC im "One-Shot"-Modus zu verwenden, dh jedes Mal, wenn mein Codec sein Flag "Ich möchte Samples" setzt, eine Konvertierung von 64 Samples für alle Kanäle auszulösen. Funktioniert das?
EDIT2 : Auf Anfrage von @Neil_UK ist hier ein anschauliches Diagramm dessen, was passiert:
4 Eingänge werden vom internen ADC des STM32 abgetastet. Jeder muss eine Abtastrate von 48 kHz haben, da die Konvertierung der ADC-Kanäle nicht parallel erfolgt, ergibt sich eine Gesamtabtastfrequenz von 192 kHz (korrigieren Sie mich, wenn ich falsch liege).
Dann werden die konvertierten Samples jedes Eingangs in einem Ringpuffer von jeweils 64 Samples gespeichert und jedes Mal, wenn ein halber Puffer gefüllt wurde (dh 32*4 Samples wurden gespeichert), wird ein Interrupt-Flag gesetzt.
Auf der anderen Seite gibt es einen Codec, der kontinuierlich Samples, die ihm per I2S zugesendet werden, aus dem DMA des STM32 umwandelt. Es wird auch jedes Mal ein Interrupt ausgelöst, wenn der halbe I2S-Puffer geleert wurde. Zwischen den 2 gibt es eine DSP-Routine, die die Eingabe lesen, filtern und in den Ausgabepuffer legen soll.
Das Problem : Ich habe 2 Interrupts:
Wenn ich mit 192 kHz scanne, sollten diese Interrupts zumindest synchron sein (außer vielleicht etwas Jitter), aber die Phase kann völlig unterschiedlich sein. Das bedeutet, dass ich meinen DAC bemerken lassen kann, dass alle Samples gesendet werden, während mein ADC noch mitten in der Konvertierung der Eingänge ist. Und diese Phasendifferenz kann möglicherweise jedes Mal anders sein, wenn ich das Board zurücksetze, sodass ich sie nicht wirklich mit einem Offset kompensieren kann.
EDIT3 : Es scheint, als wäre das SAI-Modul eine gute Möglichkeit, dies zu tun. Wenn jemand Erfahrung mit SAI hat, hätte ich gerne einige Tipps und Hilfe zur Verwendung, um den internen DAC mit einem externen Codec zu verbinden
Es gibt keine gute Möglichkeit, dies über den integrierten ADC / DAC zu tun. Sie müssten die DAC-Konvertierung im ADC-Interrupt auslösen, aber Sie könnten die Raten bei Verwendung von DMA nicht richtig einstellen, sodass Sie Sample für Sample vorgehen müssten. Das ist mit viel Overhead verbunden, und obwohl es funktionieren könnte, würde Ihnen nicht viel CPU für den DSP übrig bleiben.
Die bessere Lösung ist die Verwendung der I2S- oder SAI-Schnittstelle mit einem dedizierten Audio-Codec. Sie können entweder zwei Codecs verwenden oder einen Codec erhalten, der sowohl Eingabe- als auch Ausgabefähigkeit hat.
Neil_DE
Neil_DE
Florent
end_of_conversion
Flags werden nicht gleichzeitig gehisst. EDIT: Eigentlich muss ich gehen, ich werde meinen Beitrag so schnell wie möglich bearbeitenFlorent
Andres
Florent