AnsweredAssumed Answered

DMA transfers 25% of buffer in memory to memory mode

Question asked by Gordon Madden on Jun 29, 2017

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!

Outcomes