AnsweredAssumed Answered

SPI DMA receive problem

Question asked by asecen on Nov 18, 2013
Latest reply on Nov 19, 2013 by Clive One
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

Outcomes