STM32F207: SPI Kommunikation mit DMA

Gast #2703673
Lesenswert?
• ▲
▼
Hallo, für den Datenaustausch zwischen STM32F207 Mikrocontroller und 
einem FPGA benutzte ich die SPI Schnittstelle. Das Senden und Empfangen 
mittels Interrptroutinen funktioniert. Ich kann 16 Bit senden und 
empfange auch 16 Bit. Wenn ich nun eine Anfrage vom STM32 an den FPGA 
via SPI versende soll der FPGA mehrere 16 Bit Datenwerte an den STM32 
senden. Dazu bräuchte ich noch den DMA, der die ankommenden Daten in 
einen Puffer im DMA ablegen soll. Bei der Implementierung des DMA 
zusammen mit der SPI Schnittstelle auf dem STM32 habe ich Probleme. Wie 
könnte die Initialisierung des STM32 dazu aussehen ? Für das Empfangen 
soll ein Interrupthandler verwendet werden.
#2703681
Lesenswert?
• ▲
▼
Hier einmal einige Ausschnitte von meinem SPI Treiber: vielleicht hilft 
er dir ja weiter:

Init:
1
      // recieve
2
   DMA_DeInit(DMA1_Channel2);
3
   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x4001300C;
4
   DMA_InitStructure.DMA_MemoryBaseAddr = NULL;
5
   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
6
   DMA_InitStructure.DMA_BufferSize = 0;
7
   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
8
   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
9
   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
10
   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
11
   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
12
   DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
13
   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
14
   DMA_Init(DMA1_Channel2, &DMA_InitStructure);
15

16
   // Enable the SPI DMA RX Interrupt
17
   NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
18
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
19
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
20
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
21
   NVIC_Init(&NVIC_InitStructure); 
22

23
   // initialize SPI 
24
   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
25
   SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
26
   SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
27
   SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
28
   SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
29
   SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
30
   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
31
   SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
32
   SPI_InitStructure.SPI_CRCPolynomial = 7;
33
   SPI_Init(SPI1, &SPI_InitStructure);
34

35
   // Enable SPI DMA requests 
36
   SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);  
37
   SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);  
38
   
39
   // Enable SPI
40
   SPI_Cmd(SPI1, ENABLE);

recieve function
1
bool spiReadBytes(enum spiDevices target, uint8_t dataIn[], uint16_t countIn) {
2
   
3
   if (spiBusy == TRUE) {
4
      return FALSE;
5
   }
6
  
7
   // mark bus as busy 
8
   spiBusy = TRUE;
9

10
   if (selectSpiDevice(target) == FALSE) {
11
      return FALSE;
12
   }
13
   
14
   //increment only the destination buffer, 
15
   DMA1_Channel2->CCR |=  DMA_MemoryInc_Enable;
16
   DMA1_Channel3->CCR &= ~DMA_MemoryInc_Enable;
17
   
18
   // we will transmit only 0x00   
19
   spiDevNull = 0x00;
20
   
21
   //set DMA source address
22
   DMA1_Channel3->CMAR = (uint32_t) &spiDevNull;        
23
   DMA1_Channel2->CMAR = (uint32_t) dataIn;   
24
   
25
   // in duplex we will also recieve the same number of data
26
   DMA1_Channel2->CNDTR = countIn;
27
   DMA1_Channel3->CNDTR = countIn;
28

29
   //activated SPI DMA TC and Error IRQ   
30
   DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);
31
   DMA_ITConfig(DMA1_Channel2, DMA_IT_TE, ENABLE);
32
   DMA_ITConfig(DMA1_Channel3, DMA_IT_TE, ENABLE);   
33
   
34
   // Enable DMA1 Chanel2 and Channel3
35
   DMA_Cmd(DMA1_Channel2, ENABLE);
36
   DMA_Cmd(DMA1_Channel3, ENABLE);
37
        
38
   return TRUE;
39
}

und ein wenig IRQ
1
   // check if the transmission is complete 
2
   if (DMA_GetITStatus(DMA1_IT_TC2) != RESET) {
3
     
4
      // clear Interrupr Flag
5
      DMA_ClearITPendingBit(DMA1_IT_TC2);
6
      
7
      //deactivated DMA TC IRQ   
8
      DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, DISABLE); 
9
   
10
      // Disable DMA1 Channel2 and Channel3
11
      DMA_Cmd(DMA1_Channel2, DISABLE);
12
      DMA_Cmd(DMA1_Channel3, DISABLE);
13
      
14
      // reset all CS Lines      
15
      GPIOA->BSRR = GPIO_Pin_4; // EEPROM
16
      
17
      // mark bus as free
18
      spiBusy = FALSE;
19
   }
Gast #2703727
Lesenswert?
• ▲
▼
Hi Mike S.,

vielen Dank für den Code. So wie es aussieht verwendest du ebenfalls das 
Evaluationboard STM3220G-EVAL von STMicroelectronics. Ich benutzte die 
SPI2 Schnittstelle.

Folgende Namen sind bei mir nicht definiert:
--> DMA1_Channel2_IRQn;
--> DMA1_Channel2;
--> DMA_DIR_PeripheralSRC;
--> DMA_M2M_Disable;

Wleche DMA MemoryBaseAddr muss ich hier einstellen ? NULL wird nicht 
akzeptiert.
#2703818
Lesenswert?
• ▲
▼
Mein Code ist eine Mischung aus Library Funktionen und direkten Register 
zugriffen.

Die MemoryBaseAddr ist das Ort im Speicher, wo deine Daten 
hingeschrieben werden sollen.
Bei mir wird die erst später mit
1
DMA1_Channel2->CNDTR = countIn;
gesetzt.

Und wie Markus schon feststellte ist der Code nicht für STM32F2... 
geschrieben sondern noch für einen STM32F103. (Allerdings auf einem 
selbst entworfenem Board.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.