cancel
Showing results for 
Search instead for 
Did you mean: 

SPI with DMA is not working on STM32f2..

electronics949
Associate II
Posted on July 30, 2013 at 10:16

Hi all,

I am having problems with configuring DMA for SPI ( SPI is working without DMA).

Did anyone use  DMA with SPI3 on SMT32F2 ? Pls help me figuring out the issue...

here is my DMA code:

Problem:It is looping @ while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE) after Tx.

DMA_InitTypeDef DMA_InitStructure;   

NVIC_InitTypeDef NVIC_InitStructure1;

DMA_InitTypeDef DMA_InitStructure2;

       NVIC_InitTypeDef NVIC_InitStructure2;

     

    /* Enable DMA clock */

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

    

    DMA_DeInit(DMA1_Stream3);

    

    while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE){ }

     

    DMA_StructInit(&DMA_InitStructure);

   

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

    DMA_InitStructure.DMA_Channel = DMA_Channel_3;

    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 

    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 

    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;

    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;

    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; 

    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; 

    DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)0;

    DMA_InitStructure.DMA_BufferSize = 1;   

    

    DMA_Init (DMA1_Stream3, &DMA_InitStructure);

    

    DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE);

       

    SPI_I2S_DMACmd (SPI3, SPI_I2S_DMAReq_Tx, ENABLE);

    

    NVIC_InitStructure1.NVIC_IRQChannel = DMA1_Stream3_IRQn;

    NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 8;

    NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 8;

    NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init (&NVIC_InitStructure1);

     

    DMA_DeInit (DMA1_Stream0);

     

    while (DMA_GetCmdStatus (DMA1_Stream0) != DISABLE);

     

    DMA_StructInit (&DMA_InitStructure2);

   

    DMA_InitStructure2.DMA_PeripheralBaseAddr = (uint32_t) & (SPI3->DR);

    DMA_InitStructure2.DMA_Channel = DMA_Channel_3;

    DMA_InitStructure2.DMA_DIR = DMA_DIR_PeripheralToMemory;

    DMA_InitStructure2.DMA_MemoryInc = DMA_MemoryInc_Enable;

    DMA_InitStructure2.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 

    DMA_InitStructure2.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

    DMA_InitStructure2.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 

    DMA_InitStructure2.DMA_Mode = DMA_Mode_Normal; 

    DMA_InitStructure2.DMA_Priority = DMA_Priority_High; 

    DMA_InitStructure2.DMA_FIFOMode = DMA_FIFOMode_Enable;

    DMA_InitStructure2.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;

    DMA_InitStructure2.DMA_MemoryBurst = DMA_MemoryBurst_Single; 

    DMA_InitStructure2.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

    DMA_InitStructure2.DMA_Memory0BaseAddr = (uint32_t)0; 

    DMA_InitStructure2.DMA_BufferSize = 1;

   

    DMA_Init (DMA1_Stream0, &DMA_InitStructure2);

     

    /*Cofigure transfer complete interrupt*/

    DMA_ITConfig (DMA1_Stream0, DMA_IT_TC, ENABLE); // Transfer complete interrupt mask    

     

    NVIC_InitStructure_RX.NVIC_IRQChannel = DMA1_Stream0_IRQn;

    NVIC_InitStructure_RX.NVIC_IRQChannelPreemptionPriority = 7; 

    NVIC_InitStructure_RX.NVIC_IRQChannelSubPriority = 7;

    NVIC_InitStructure_RX.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init (&NVIC_InitStructure_RX);

    

    /* Enable dma rx request. */

    SPI_I2S_DMACmd (SPI3, SPI_I2S_DMAReq_Rx, ENABLE);

    SPI_I2S_DMACmd (SPI3, SPI_I2S_DMAReq_Tx || SPI_I2S_DMAReq_Rx, ENABLE);

    

    /* Tx */

unsigned char temp[4];

temp[0] = 0xA0;

temp[1] = 0xB1;

temp[2] = 0x5C;

temp[3] = 0xC3;

    DMA1_Stream3->PAR = (uint32_t) & (SPI3->DR);

DMA1_Stream3->NDTR = (uint32_t) 4;

DMA1_Stream3->M0AR = (uint32_t) &(temp[0]);

DMA_Cmd (DMA1_Stream3, ENABLE);

while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE)

{

printf(''success\n'');

}

/* Rx */

DMA1_Stream0->PAR = (uint32_t) & (SPI3->DR);

DMA1_Stream0->NDTR = (uint32_t) 4;

DMA1_Stream0->M0AR = (uint32_t) &(temp[0]);            

DMA_Cmd (DMA1_Stream0, ENABLE);

while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) == SET);

DMA1_Stream3->PAR = (uint32_t) & (SPI3->DR);

DMA1_Stream3->NDTR = (uint32_t) 4;

DMA1_Stream3->M0AR = (uint32_t) &(temp[0]) ;      

DMA_Cmd (DMA1_Stream3, ENABLE);

while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE)

{

printf(''success\n'');

}

        

Thanks in advance.

4 REPLIES 4
Posted on July 30, 2013 at 12:44

You've just ENABLEd the DMA stream, so it is not unreasonable that it != DISABLE...

JW

electronics949
Associate II
Posted on July 30, 2013 at 13:34

hi waclawek.jan,


Thanks for the reply,
According my understanding it should trigger the transfer as soon as the DMA stream is enabled,and hardware disables the DMA stream at the end of the transfer, so I was waiting for it.
I tried even checking for Tx complete interrupt but still same issue.
while(!DMA_GetFlagStatus(DMA1_Stream3, DMA_FLAG_TCIF3));
and observed a weird case i.e., Tx complete interrupt is getting triggered after disabling the DMA.

Posted on July 30, 2013 at 14:03

Ah, I see.

---

Why are you trying to use DMA1 Stream3/Channel3 and Stream0/Channel3? According to RM0033 Table 22, those are mapped to I2S2_ext_RX and I2S3_ext_RX respectively.

JW
electronics949
Associate II
Posted on July 30, 2013 at 14:51

Hi JW,

Thanks you very much pointing it out. It really helped a lot.

I thought we can use any stream/channel for SPI interface.

Thanks

Sagar