[STM32 SAI] Warum läuft DMA in Schleife?

OP #5739374
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);
OP #5739401
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.
OP #5739413
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
OP #5739616
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren