Skip to main content
intcd31
Associate II
September 18, 2014
Question

SPI DMA Rx transfer error

  • September 18, 2014
  • 11 replies
  • 1983 views
Posted on September 18, 2014 at 02:05

I want to change polling SPI to DMA SPI. Now I get stuck and have looked up lots of material. None of them is working for me. 

The original polling SPI code works fine. I implemented the following code for the DMA. Something weird happened here. It seems there is no problem for TX  but the RX DMA gets transfer error. SxNDT register still 0x78. I don't know the reason.

1. Should the amount of RX data be the same as TX? But Rx doesn't receive anything.

2. The TX source is from external memory by FMC. Does it matter?

void SPI1_DMA_Configuration()

{

    DMA_InitTypeDef DMA_InitStructure;

    DMA_Cmd(DMA2_Stream3, DISABLE);

    DMA_Cmd(DMA2_Stream2, DISABLE);

    DMA_ClearITPendingBit(DMA2_Stream3,DMA_IT_TCIF3);

    DMA_ClearITPendingBit(DMA2_Stream2,DMA_IT_TCIF2);

    DMA_DeInit(DMA2_Stream3);

    while (DMA_GetCmdStatus (DMA2_Stream3) != DISABLE);

    DMA_StructInit(&DMA_InitStructure);

    // TX

    DMA_InitStructure.DMA_Channel = DMA_Channel_3;

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

    DMA_InitStructure.DMA_BufferSize = 10000;

    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) HEADER_ADDR;

    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;

    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//DMA_PeripheralDataSize_HalfWord;

    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//DMA_MemoryDataSize_HalfWord;

    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;

    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;

    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;

    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

    DMA_Init(DMA2_Stream3, &DMA_InitStructure);

    // RX

    DMA_DeInit(DMA2_Stream2);

    while (DMA_GetCmdStatus (DMA2_Stream2) != DISABLE);

    DMA_StructInit(&DMA_InitStructure);

    DMA_InitStructure.DMA_Channel = DMA_Channel_3;

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

    DMA_InitStructure.DMA_BufferSize = 120;

    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &SPIReceiveBuffer[0];

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//DMA_PeripheralDataSize_HalfWord;

    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//DMA_MemoryDataSize_HalfWord;

    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;

    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;

    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;

    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

    DMA_Init(DMA2_Stream2, &DMA_InitStructure);

    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx, ENABLE);

    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Rx, ENABLE);

    while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));                // wait for empty TX buffer

    DMA_Cmd(DMA2_Stream2, ENABLE);

    DMA_Cmd(DMA2_Stream3, ENABLE);

    

    while ( DMA_GetCmdStatus(DMA2_Stream3) != ENABLE );

    while ( DMA_GetCmdStatus(DMA2_Stream2) != ENABLE ); 

    SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, DISABLE);

    SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, DISABLE);

}

This is my first time to ask questions. Thank you for your help.
    This topic has been closed for replies.

    11 replies

    intcd31
    intcd31Author
    Associate II
    September 18, 2014
    Posted on September 18, 2014 at 17:16

    JW, thank you for this. I got stuck on this for a while. Never thought about this.

    How can I make sure the parameters I declared NOT using CCM?