AnsweredAssumed Answered

SPI with DMA on STM32F437

Question asked by psykhi on Jun 23, 2015
Latest reply on Jun 29, 2015 by peacock.jack.003
Hi,

I'm having troubles setting up the DMA with SPI2 on a STM32F437. I am using the streams 3 and 4 on channel 0 as said in the datasheet. Here is my init code :
void MX_SPI2_Init(void)
{
  DMA_InitTypeDef DMA_InitStructure; //Variable used to setup the DMA
 
  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLED;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
  hspi2.hdmarx =&dmarx;
  hspi2.hdmatx =&dmatx;
  HAL_SPI_Init(&hspi2);
}

Then the MSP init :
01.__DMA1_CLK_ENABLE();
02. 
03.    dmatx.Init.Channel = DMA_CHANNEL_0;
04.    dmatx.Init.Direction = DMA_MEMORY_TO_PERIPH;
05.    dmatx.Init.PeriphInc = DMA_PINC_DISABLE;              
06.    dmatx.Init.MemInc = DMA_MINC_DISABLE;               
07.    dmatx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
08.    dmatx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; 
09.    dmatx.Init.Mode = DMA_NORMAL;               
10.    dmatx.Init.Priority = DMA_PRIORITY_HIGH;           
11.    dmatx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;        
12.    dmatx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
13.    dmatx.Init.MemBurst = DMA_MBURST_SINGLE;             
14.    dmatx.Init.PeriphBurst = DMA_PBURST_SINGLE;         
15. 
16.    dmatx.Instance = DMA1_Stream4;
17. 
18. 
19.    HAL_DMA_Init(&dmatx);
20.    __HAL_LINKDMA(&hspi2, hdmatx, dmatx);
21.    HAL_NVIC_SetPriority(DMA1_Stream4_IRQn,8,0);
22.    HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
23. 
24. 
25.    dmarx.Init.Channel = DMA_CHANNEL_0;
26.    dmarx.Init.Direction = DMA_PERIPH_TO_MEMORY;
27.    dmarx.Init.PeriphInc = DMA_PINC_DISABLE;            
28.    dmarx.Init.MemInc = DMA_MINC_DISABLE;              
29.    dmarx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
30.    dmarx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
31.    dmarx.Init.Mode = DMA_NORMAL;                
32.    dmarx.Init.Priority = DMA_PRIORITY_MEDIUM;        
33.    dmarx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;        
34.    dmarx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
35.    dmarx.Init.MemBurst = DMA_MBURST_SINGLE;           
36.    dmarx.Init.PeriphBurst = DMA_PBURST_SINGLE;        
37. 
38.    dmarx.Instance = DMA1_Stream3;
39. 
40. 
41.    HAL_DMA_Init(&dmarx);
42.    __HAL_LINKDMA(&hspi2, hdmarx, dmarx);
43.    HAL_NVIC_SetPriority(DMA1_Stream3_IRQn,8,0);
44.    HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);

Then I call HAL_SPI_Transmit_DMA from my code which prepares the DMA transmission and registers the interrupt. The TX interrupt is then fired with no error flags, but the code hangs in the SPI transmit callback function because the TXE flags never resets in the SPI.

My DMA seems to be correctly configured, the target address is the address of the SPI DR register, the byte count is correct, so is the source address. If I check with a scope, nothing comes out of the µC (it works without the DMA).

So I guess there's something missing in my initialization, but I can't figure out what... Any ideas ?

Thanks !



Outcomes