cancel
Showing results for 
Search instead for 
Did you mean: 

SPI DMA receive problem

asecen89
Associate II
Posted on November 18, 2013 at 14:03

Hi,

I am using SPI with DMA in STM32F427 for full duplex communication with another processor. My configuration for SPI and DMA is follows;

   

    SPI_InitTypeDef SPI_InitStructure;       

    GPIO_InitTypeDef GPIO_InitStructure;

    DMA_InitTypeDef DMA_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

       

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);   

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

   

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);    // SCK

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);    // MISO

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);    // MOSI

   

    //Configure the pins used for SPI

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;     

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;         

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    SPI_I2S_DeInit(SPI2);

   

    SPI_StructInit(&SPI_InitStructure);    

   

    // SPI configuration

    SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;         

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;        

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;         

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;        

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;      

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;        

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_InitStructure.SPI_CRCPolynomial = 7;

    SPI_Init(SPI2, &SPI_InitStructure);      

    SPI_Cmd(SPI2, ENABLE);        

   

    /*********************************************************************************************/

   

    // DMA for Tx

    DMA_DeInit(DMA1_Stream4);       

                                                         

    DMA_StructInit(&DMA_InitStructure);        

   

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (SPI2->DR);        

    DMA_InitStructure.DMA_Channel = DMA_Channel_0;         

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;        

    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;        

    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;         

    DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)  &Tx_Buffer_to_AP1;     

    DMA_InitStructure.DMA_BufferSize = 8;      

    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;         

    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;   

    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;      

    DMA_InitStructure.DMA_PeripheralInc = DMA_MemoryInc_Disable; 

    DMA_DoubleBufferModeConfig (DMA1_Stream4 ,(uint32_t)  &Tx_Buffer_to_AP2, DMA_Memory_0);

    DMA_DoubleBufferModeCmd(DMA1_Stream4 , ENABLE);        

    DMA_InitStructure.DMA_Priority = DMA_Priority_High;    

    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;

    DMA_InitStructure.DMA_PeripheralBurst = DMA_MemoryBurst_INC4;

           

    DMA_Init(DMA1_Stream4 , &DMA_InitStructure);        

   

    /************************************************************************************/

    // DMA for Rx

    DMA_DeInit(DMA1_Stream3);    

    DMA_StructInit(&DMA_InitStructure);

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (SPI2->DR);        

    DMA_InitStructure.DMA_Channel = DMA_Channel_0;

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;    

    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;      

    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)  &Rx_Buffer_from_AP;

    DMA_InitStructure.DMA_BufferSize = 40968;        

    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;         

    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; 

    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; 

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;       

    DMA_InitStructure.DMA_PeripheralInc = DMA_MemoryInc_Disable;  

    DMA_InitStructure.DMA_Priority = DMA_Priority_High;        

    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;   

    DMA_InitStructure.DMA_PeripheralBurst = DMA_MemoryBurst_INC4;

    DMA_Init(DMA1_Stream3 , &DMA_InitStructure);   

   

    /***************************************************************************************/

    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn;       

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

   

   

    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream3_IRQn;       

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

   

    DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE);    

    DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, ENABLE);

   

    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);        

    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);

In the DMA interrupts, I clear the TCIF3 and TCIF4 flags and DMA is enabled in the main part of the code. There is no problem regarding the Tx part of the SPI, it works fine, but it only receives the data at first access of the master device and as a result, it goes into receive interrupt only once. I spent hours trying to figure out why this happens, but so far I have got no result. Can anybody can help me out on this? 

Thanks,

Ali
2 REPLIES 2
asecen89
Associate II
Posted on November 19, 2013 at 14:46

In addition to my previous question, do you think is it possible to set different buffer sizes for Tx and Rx when using SPI with DMA?

Posted on November 19, 2013 at 16:23

I don't think the SPI controller cares unless you stop servicing it.

NOT MEMORY

    DMA_InitStructure.DMA_PeripheralInc = DMA_MemoryInc_Disable;  

    DMA_InitStructure.DMA_PeripheralBurst = DMA_MemoryBurst_INC4;

If the DMA is failing check to see if it has some fault or error condition. Never particularly cared for the double-buffering mode provided by ST. If you have a linear buffer, you can split it with HT and TC interrupts.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..