cancel
Showing results for 
Search instead for 
Did you mean: 

DMA transfers 25% of buffer in memory to memory mode

Gordon Madden
Associate III
Posted on June 29, 2017 at 23:46

Using STM32F417 DMA and got it to work but it only transfers 25% of the buffer size indicated. So far, I have tested the following buffer sizes:

Buffer size (bytes)            Bytes transferred

10                                                3

25                                                7

1000                                          250

So, that's 25% ceiling to the next higher integer. If there is some other math relationship, please let me know.

Here is my code for the DMA, followed by the interrupt handler:

#define DMA_STREAM                   DMA2_Stream0

#define DMA_CHANNEL                  DMA_Channel_0

#define DMA_STREAM_CLOCK             RCC_AHB1Periph_DMA2

#define DMA_STREAM_IRQ               DMA2_Stream0_IRQn

#define DMA_IT_TCIF                  DMA_IT_TCIF0

#define DMA_STREAM_IRQHANDLER        DMA2_Stream0_IRQHandler

void InitDMAmemory( void )  //////////////////////////////////////////////////

{

    DMA_InitTypeDef dma_mem;

    NVIC_InitTypeDef NVIC_InitStructure;

    uint32_t Timeout = TIMEOUT_MAX;

 

    // Start the DMA clock

    RCC_AHB1PeriphClockCmd(DMA_STREAM_CLOCK, ENABLE);

    

    // DeInit to reset DMA config to default reset value

    DMA_DeInit(DMA_STREAM);             

    while(DMA_GetCmdStatus(DMA_STREAM) != DISABLE)

    {

    }

    

    // Set values for parameters

    dma_mem.DMA_Channel                = DMA_CHANNEL;

    dma_mem.DMA_Memory0BaseAddr        = (uint32_t)memBuffer; 

    dma_mem.DMA_PeripheralBaseAddr     = (uint32_t)periphBuffer; 

    dma_mem.DMA_MemoryDataSize         = DMA_MemoryDataSize_Byte;  

    dma_mem.DMA_PeripheralDataSize     = DMA_PeripheralDataSize_Byte; 

    dma_mem.DMA_DIR                    = DMA_DIR_MemoryToMemory;

    dma_mem.DMA_Mode                   = DMA_Mode_Normal; 

    dma_mem.DMA_MemoryInc              = DMA_MemoryInc_Enable;

    dma_mem.DMA_PeripheralInc          = DMA_PeripheralInc_Enable;

    dma_mem.DMA_BufferSize             = BUFFERSIZE;

    dma_mem.DMA_Priority               = DMA_Priority_High;

    dma_mem.DMA_MemoryBurst            = DMA_MemoryBurst_Single;

    dma_mem.DMA_PeripheralBurst        = DMA_PeripheralBurst_Single;  

    dma_mem.DMA_FIFOMode               = DMA_FIFOMode_Enable;

    dma_mem.DMA_FIFOThreshold          = DMA_FIFOThreshold_HalfFull; 

    

    DMA_Init(DMA_STREAM, &dma_mem);     

    DMA_ITConfig(DMA_STREAM,DMA_IT_TC, ENABLE);   

  while ((DMA_GetCmdStatus(DMA_STREAM) != ENABLE) && (Timeout-- > 0))

  {

  }

   

  /* Check if a timeout condition occurred */

  if (Timeout == 0)

  {

    /* Manage the error: to simplify the code enter an infinite loop */

    while (1)

    {

    }

  }

    

    /*Enable DMA1 Stream IRQ Channel */

    NVIC_InitStructure.NVIC_IRQChannel                       = DMA_STREAM_IRQ;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority     = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority            = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd                    = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    

    DMA_Cmd(DMA_STREAM, ENABLE);   

} // end InitDMAmemory  ///////////////////////////////////////////////////////////

void DMA_STREAM_IRQHANDLER( void )  //////////////////////////////////////////////

{

     //Test on DMA1 Channel1 Transfer Complete interrupt

  if(DMA_GetITStatus(DMA_STREAM, DMA_IT_TCIF))

  {

      status=1;

        

    DMA_ClearITPendingBit(DMA_STREAM,DMA_IT_TCIF);

    DMA_Cmd(DMA_STREAM,DISABLE);

    DMA_ITConfig(DMA_STREAM, DMA_IT_TC, DISABLE);

    }

    

} // end DMA1_Stream3_IRQHandler  //////////////////////////////////////////////////

I can't figure out why the whole transfer is not being completed. Is the transfer complete interrupt occurring early? Why does do a percentage instead of a discrete number?

Thank you for your help!

0 REPLIES 0