Forum: Mikrocontroller und Digitale Elektronik [STM32 SAI] Warum läuft DMA in Schleife?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Solocan Z. (solocan)


Bewertung
0 lesenswert
nicht lesenswert
Ich stehe vor einem seltsamen Verhalten, das ich mir nicht erklären 
kann:

Ich will (beispielhaft) ein einziges 32-bit Word über DMA ins 
Datenregister von SAI schreiben. Also ich will, dass das erwünschte 
Datenblock ins FIFO geht, wenn es vollständig übertragen ist, ein 
Callback auslöst und aufhört. Im normalen (Blocking) Modus funktioniert 
das, wenn ich es mit DMA mache, läuft die DMA die ganze Zeit im 
Hintergrund.

Aber das geschriebene Wort wird von einem Mechanismus dauerhaft ins FIFO 
gefüllt und in Schleife ausgegeben. D.h. ich kriege kein Transfer 
complete callback etc. Wodurch wird die DMA die ganze Zeit getriggert?

Das folgende vereinfachte Programm gibt das Wort "buf" in Schleife 
wieder, siehe Bild.  https://ibb.co/1K5tn7G (Gerade lassen sich keine 
Bilder hier hochladen?)

1
//Programmcode
2
uint32_t buf=0b10101010101010101100110011001100;
3
HAL_SAI_Transmit_DMA2(&hsai_BlockA1, (uint8_t*)&buf, 1);
4
5
//DMA Transmit Funktion
6
7
HAL_StatusTypeDef HAL_SAI_Transmit_DMA2(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size){
8
9
    HAL_DMA_Start(hsai->hdmatx, (uint32_t)pData, (uint32_t)&hsai->Instance->DR, Size);
10
11
    // Enable SAI
12
    __HAL_SAI_ENABLE(hsai);
13
14
    /* Enable SAI Tx DMA Request */
15
    hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
16
17
    return HAL_OK;
18
19
}
20
21
//Konfiguration SAI
22
23
  hsai_BlockA1.Instance = SAI1_Block_A;
24
  hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_TX;
25
  hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS;
26
  hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
27
  hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
28
  hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_HF;
29
  hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_8K;
30
  hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
31
  hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
32
  hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
33
  hsai_BlockA1.Init.TriState = SAI_OUTPUT_NOTRELEASED;
34
  HAL_SAI_InitProtocol(&hsai_BlockA1, SAI_I2S_MSBJUSTIFIED, SAI_PROTOCOL_DATASIZE_32BIT, 2);
35
36
//Konfiguration DMA
37
38
__HAL_RCC_DMA2_CLK_ENABLE();
39
40
 hdma_sai1_a.Instance=DMA2_Stream1;
41
 hdma_sai1_a.Init.Channel = DMA_CHANNEL_0;// Channel 0, Stream 0
42
 hdma_sai1_a.Init.Direction=DMA_PERIPH_TO_MEMORY;
43
 hdma_sai1_a.Init.PeriphInc=DMA_PINC_DISABLE;
44
 hdma_sai1_a.Init.MemInc=DMA_MINC_DISABLE;
45
 hdma_sai1_a.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;
46
 hdma_sai1_a.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;
47
 hdma_sai1_a.Init.Mode=DMA_NORMAL;
48
 hdma_sai1_a.Init.Priority=DMA_PRIORITY_HIGH;
49
 hdma_sai1_a.Init.FIFOMode=DMA_FIFOMODE_DISABLE;
50
 hdma_sai1_a.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_HALFFULL;
51
 hdma_sai1_a.Init.MemBurst=DMA_MBURST_SINGLE;
52
 hdma_sai1_a.Init.PeriphBurst=DMA_PBURST_SINGLE;
53
 hdma_sai1_a.XferCpltCallback  = HAL_DMA_XFER_HALFCPLT_CB_ID;
54
55
//Initialize DMA
56
HAL_DMA_Init(&hdma_sai1_a);

von Martin B. (ratazong)


Bewertung
0 lesenswert
nicht lesenswert
Blick Dein Programm nicht ganz, aber was mir auffällt:

hdma_sai1_a.Init.MemInc=DMA_MINC_DISABLE;

müsste da nicht enable stehen? Die Adressen im memorry sollten doch 
incrementiert werden.


hdma_sai1_a.XferCpltCallback  = HAL_DMA_XFER_HALFCPLT_CB_ID;

Wieso HALFCPLT ?

von Solocan Z. (solocan)


Bewertung
-1 lesenswert
nicht lesenswert
Martin B. schrieb:
> Blick Dein Programm nicht ganz, aber was mir auffällt:
>
> hdma_sai1_a.Init.MemInc=DMA_MINC_DISABLE;
>
> müsste da nicht enable stehen? Die Adressen im memorry sollten doch
> incrementiert werden.
>
>
> hdma_sai1_a.XferCpltCallback  = HAL_DMA_XFER_HALFCPLT_CB_ID;
>
> Wieso HALFCPLT ?

Nein, meine Quell- und Zieladresse sind fest. Die Daten kommen auch 
richtig an. Nur es hört nach einem Transfer nicht auf...(Das mit dem 
Enablen habe ich auch probiert, bringt nichts.)

Das Problem ist, als wäre der Circular mode aktiv, obwohl ich es 
deaktiviert habe (Normal mode aktiv)

HALFCPLT ist auskommentiert. Einfach ignorieren.

: Bearbeitet durch User
von Martin B. (ratazong)


Bewertung
0 lesenswert
nicht lesenswert
Willst Du immer nur ein byte übertragen?

Was macht das Programm denn, wenn Du DMA_MINC_ENABLE da rein schreibst?
Würde mich mal interessieren.
Grüße

von Solocan Z. (solocan)


Bewertung
-1 lesenswert
nicht lesenswert
Martin B. schrieb:
> Willst Du immer nur ein byte übertragen?

Nein, ich möchte um die 48 Word große Datenblöcke übertragen, aber nicht 
in Schleife. Das Verhalten ist aber dasselbe, ich habe nur den 
Programmcode vereinfacht, um es zu zeigen.

Martin B. schrieb:
> Was macht das Programm denn, wenn Du DMA_MINC_ENABLE da rein schreibst?

Genau dasselbe. Es ändert sich nichts. Weiterhin in Schleife

von Martin B. (ratazong)


Bewertung
0 lesenswert
nicht lesenswert
da fällt mir nicht mehr viel ein.

willst Du DMA_MEMORY_TO_PERIPH oder DMA_PERIPH_TO_MEMORY ?

aber Du sagst ja es funktioniert. Merkwürdig.

von Solocan Z. (solocan)


Bewertung
-1 lesenswert
nicht lesenswert
Martin B. schrieb:
> Merkwürdig

Was auch sehr merkwürdig ist, dass jemand alle meiner Beiträge pauschal 
negativ bewertet. Das ist sehr merkwürdig. Na ja.

Ich habe gerade festgestellt, dass SAI Initialisierung die DMA 
Einstellungen überschreibt. HAL eben...Jetzt versuche ich 
herauszufinden, wie und wo und warum sie das tut.

von Solocan Z. (solocan)


Bewertung
0 lesenswert
nicht lesenswert
Fehler gefunden:

Die DMA wird in "HAL_SAI_MspInit()" in der Datei "stm32f7xx_hal_msp.c" 
intialisiert. Da ich das nicht sah, hatte ich eine andere Instanz in 
meiner "main.c" definiert. Meine Instanz samt Einstellungen wurde 
natürlich überschrieben.

Also konkret lag's wie vermutet an DMA mode. "DMA_NORMAL" läuft einmal 
und "DMA_CIRCULAR" läuft in Schleife.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.