Forum: Mikrocontroller und Digitale Elektronik STM32 I2S mit DMA


von FabianA. (Gast)


Lesenswert?

Hallo!

Ich beschäftige mich gerade etwas mit I2S und dem DMA.
Dabei bin ich auf ein paar Verständnisprobleme gestoßen.

Im Setup ist ein STM32F4 mit einem Audio Codec verbunden.
Der Audio Codec schickt dabei die Daten über die I2S Leitung an den 
STM32.
Dieser verarbeitet die Daten und sendet sie zurück n den Audio Codec.

Dabei verstehe ich aber nicht, wie die eingehenden Daten gespeichert 
werden.

HAL_I2SEx_TransmitReceive_DMA(&handler_i2s, buf_out, buf_in, 
sizeof(buf_out)/2);

Ich finde die Beschreibung der Funktion etwas dürftig:
pTxData  a 16-bit pointer to the Transmit data buffer.
pRxData  a 16-bit pointer to the Receive data buffer.

Füllt der DMA nun selbstständig den buf_in mit Daten?

Dabei gibt es noch die beiden Interrupt-Routinen
HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)

In diesen Funktionen wird das verarbeiten der Daten angestoßen.
Korrekterweiße steht in der Beschreibung auch:
"Tx Transfer completed callbacks."

Sollte es aber nicht eigentlich so sein, dass der Codec die Daten per 
I2S an den STM sendet und dieser die Daten direkt in den buf_in 
schreibt.
Nun werden beim befüllen zwei Interrupts ausgelöst:
HAL_I2S_RxHalfCpltCallback und HAL_I2S_RxCpltCallback (Rx statt Tx)
In diesen Funktionen werden die buf_in Daten verarbeitet, in den buf_out 
geschrieben und der DMA gibt es an dieser Stelle per I2S wieder an den 
Codec.

Irgendwie wird wir die Vorgehensweise nicht ganz klar und leider ist die 
Dokumentation echt nicht soo toll bzw. ich kann damit eher weniger 
anfangen.

Grüße Fabian!

von W.S. (Gast)


Lesenswert?

I2S ist eigentlich synchron und besteht im Grunde aus Bit-Clock, Input, 
Output und L/R-Clock. Letzteres gilt als Kennzeichen, wann ein 
übertragenes Wort beginnt. Und übertragen wird (nicht immer, aber 
zumeist) ein Block aus 32 Bit für links und 32 Bit für rechts. Macht 64 
Bit aus, gelle.

Guck dir den/die I2S-Core(s) im Referenzmanual an und versuche zunächst 
zu verstehen, wie dort die Peripherie funktioniert. Bei den STM32 ist 
die Peripherie an vielen Stellen noch immer 16 bittig und das, was man 
gelegentlich als I2S angepriesen kriegt, ist dann nur ein etwas 
erweitertes SPI, was dann aber ebne auch 16 bittig bedient sein will.

Da sowas per Interrupt (mit der 4fachen Frequenz wie die Samplerate, 
4*16-->64 Bit) ausgesprochen unangenehm ist und solche popligen 
I2S-Cores keine Fifos haben, kommt da eben DMA ins Spiel, was die ganze 
Sache weiter verkompliziert.

Schau im RefMan auch mal nach einem SAI-Core, das steht für  serielles 
audio interface und ist sozusagen die bessere Variante von I2S. Wenn 
vorhanden, nimm dieses SAI als I2S-Anschluß. Zumeist haben diese SAI 
auch Fifo's.

Ich würde an deiner Stelle einen Chip mit SAI nehmen, dieses SAI dann 
zunächst mit Interrupts bedienen, bis das Ding, was du damit bauen 
willst wenigstens prinzipiell funktioniert und dann zusehen, wie die 
Interruptfunktion direkt am SAI per DMA ersetzt und entschärft werden 
kann.

Wenn du alles zugleich machen willst, dann hast du nix, worauf du dich 
zunächst verlassen kannst - und Herumdebuggen bei einem Interface, was 
mit 48 oder 96 oder 192 kSamples/s durchläuft und eigentlich nicht 
anhaltbar ist, macht gewiß keine Freude.

W.S.

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.