Forum: Mikrocontroller und Digitale Elektronik STM32 DMA Controller zurücksetzen


von Bernhard L. (bernhard_r84)


Lesenswert?

Hallo!
Wie kann man im STM32 den DMA Controller (in meinem Fall DMA1_Channel2) 
komplett zurücksetzen?
Ich möchte eigentlich nur einen Buffer mit Daten vom SPI Interface 
füllen.
Die Initialisierung sowie das Neusetzen der Buffergröße erfolgt mit 
dieser Funktion.
1
void DMA_Configuration(uint32_t sample_buffersize)
2
{
3
  DMA_InitTypeDef    DMA_InitStructure;
4
5
  /* SPI1 MASTER RX DMA_Channel (DMA1_Channel2) configuration ---------------------------------*/
6
  DMA_DeInit(DMA1_Channel2);
7
  DMA_StructInit(&DMA_InitStructure);
8
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI1->DR));
9
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&sample_buffer;
10
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
11
  DMA_InitStructure.DMA_BufferSize = sample_buffersize;
12
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
13
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
14
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
15
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
16
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
17
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
18
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
19
  DMA_Init(DMA1_Channel2, &DMA_InitStructure);
20
21
  /* Enable DMA1 Channel2 Transfer Complete interrupt */
22
  DMA_ITConfig(DMA1_Channel2, DMA_IT_TC | DMA_IT_HT, ENABLE);
23
24
  /* Enable DMA1 Channel2 transfer */
25
  DMA_Cmd(DMA1_Channel2, ENABLE);
26
}


Das Problem ist aber, daß neue Daten an eine falsche Stelle von 
sample_buffer geschrieben werden.
Daher vermute ich daß die internen Register des DMA-Kanals nicht richtig 
zurückgesetzt wurden.
Nach einem Reset klappt alles einwandfrei, nur nach nochmaligem Aufrufen 
der Funktion passiert der Fehler.
Das Einlesen der Daten wird zum passenden Zeitpunkt manuell getriggert 
indem einfach ein Datenwort über SPI gesendet werden (SPI1->DR = 0;)
Das SPI Device bekommt seine Clock-Impulse und sendet die Daten an den 
Controller. Das empfangene Datenwort soll per DMA in den Buffer 
geschrieben werden bis nach n Transfers dieser gefüllt ist. Die 
Auswertung erfolgt in den Interrupt-Routinen HT2 (buffer start bis 
buffer / 2) und TC2 (buffer / 2 bis buffer ende)

Habe ich irgendwo einen Denkfehler?

Grüße,
Bernhard

von Holger (Gast)


Lesenswert?

Hallo Bernard,

du musst den DMA Handler erst deaktivieren (DMA_Cmd(DMA1_Channel2, 
DISABLE);) bevor du die Register wieder (korrekt) setzen kannst.

Grüße

Holger

von friedrich (Gast)


Lesenswert?

Hallo Bernhard,

mit "DMA_InitStructure.DMA_Mode = DMA_Mode_Circular" sagst Du dem DMA 
Controller dass er am Ende der Übertragungslänge am Puffer neu anfangen 
soll. Ist das auch so gewünscht?. Nach einer nicht ganz vollen 
Übertragung des Puffers wird der DMA also nicht wieder am Puffer 
anfangen sondern dort aufhören wo er mit "sample_buffersize" bisher 
hingekommen ist (heißt: wenn Du den Puffer 256 Byte groß gemacht hast 
und der DMA bisher erst 20 Byte überrtagen hat geht die nächste 
Übertragung in Location 21. Wenn er dann bei Location 256 angekommen ist 
und immer noch Übertragne muss (weil eine Anforderung) kommt geht der 
nächste Transfer eben in Location 0 (Circular).

Grüße

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.