Forum: Mikrocontroller und Digitale Elektronik STM32 IS2 HAL DMA Buffer Probleme beim füllen


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 Audionaer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche gerade per I2S und DMA ein Soundstück im Loop mit einer 
Rohlänge von 4096 abzuspielen.
Wenn ich meinen Buffer direkt und in voller Länge übergebe funktioniert 
es auch gut.

Nur muss ich mit FIFO Buffern arbeiten, weil ich das Soundstück vorher 
durch Filter zum dezunieren/interpolieren jagen muss. Da ändert sich 
nach dem Filter ja die Länge.

Im ersten Schritt konnte ich jeweils bei dem half und full Interrupt 
Callbacks meinen dedizierten DMA Buffer jeweils um 2048 füllen.
bei half die ersten 2048 und beim full die zweiten 2048 aus dem 
rohSound.
Das hatte auch noch gut geklappt.

Da ich jetzt aber einen Buffer mit einer varaiblen Größe haben muss kann 
ich den oberen Ansatz ja nicht mehr fahren.

Hilfsweise habe ich diesen Ansatz implementiert. Nur scheint es 
irgendwie nicht zu klappen, soll heißen, das der Buffer anscheinend 
nicht schnell genug gefüllt wird.
1
#define DMABUFF_SIZE 256
2
3
uint16_t PlayBuff[4096];
4
uint16_t DMABuff[DMABUFF_SIZE];
5
uint16_t ptrPlayBuff;
6
uint16_t PlayBuffSize = 4096;
7
uint16_t ptrPlayBuffFill;
8
uint16_t fillSize=1024;
9
uint16_t ptrSound=0;
10
uint16_t soundSize=4096;
11
12
void PlayBuffFill(void);
1
void PlayBuffFill(void)
2
{
3
  uint16_t i;
4
  for(i=fillSize*ptrPlayBuffFill;i<fillSize*(ptrPlayBuffFill+1);i++)
5
  {
6
    PlayBuff[i] = sound0[ptrSound];
7
    ptrSound++;
8
  }
9
  
10
  PlayBuffSize = fillSize*(ptrPlayBuffFill+1);
11
  ptrPlayBuffFill++;
12
  if(ptrSound==soundSize)
13
    ptrSound=0;
14
  
15
}
16
17
18
void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) {
19
  uint16_t i;
20
21
  for(i=0;i<(DMABUFF_SIZE/2)-1;i++)
22
  {
23
    DMABuff[i]=PlayBuff[ptrPlayBuff];
24
    ptrPlayBuff++;
25
  }
26
  
27
   if(ptrPlayBuff==PlayBuffSize)
28
    ptrPlayBuff=0;
29
    PlayBuffFill();
30
  
31
}
32
33
void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) {
34
  uint16_t i;
35
  
36
  for(i=(DMABUFF_SIZE/2)-1;i<DMABUFF_SIZE;i++)
37
  {
38
    DMABuff[i]=PlayBuff[ptrPlayBuff];
39
    ptrPlayBuff++;
40
  }
41
  if(ptrPlayBuff==PlayBuffSize)
42
    ptrPlayBuff=0;
43
  
44
  
45
}


Der Aufruf in der main sieht so aus, wobei ich den Buffer initial 
schonmal fülle
1
PlayBuffFill();
2
HAL_I2S_Transmit_DMA(&hi2s3,DMABuff ,DMABUFF_SIZE);


Was läuft hier eigentlich falsch?
Leider kann ich das nicht erkennen und hoffe hier einen entscheidenden 
Hinweis zu bekommen.

Rahmenparameter sind: STMF303 mit 72MHz Systemtakt und I2S mit einer 
samplingrate von 8kHz.

von Jim M. (turboj)


Bewertung
0 lesenswert
nicht lesenswert
Ich sehe da einen Buffer Overflow mit "ptrPlayBuffFill", das nicht auf 
die Puffergröße begrenzt wird.

Ob die 3-fach Kopie (sound0->PlayBuff->DMABuff) noch schnell genug ist - 
das ist dann auch eine gute Frage, und vermutlich abhängig vom 
Optimizer.

Einer der Puffer - PlayBuff oder DMABuff - ist IMHO überflüssig, 
zumindest im geposteten Codeabschnitt.

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.