AnsweredAssumed Answered

Double buffered DMA Interrupt not working

Question asked by mentink.bernard on Aug 2, 2014
Latest reply on Aug 2, 2014 by mentink.bernard
Hi All,

New to the STM32 so please bare with me....

I have setup timer4 to generate a sinewave modulated PWM using double buffered DMA and that works very well, I can see my waveform on the pin and it contains the correct data from each of the two buffers.

However, I am trying to update the buffers via the half completed interrupt and I don't seem to be getting any action at all ...

The code that sets up the DMA and the interrupt and the interrupt routine itself follows:

-------------------------------------------------------------------
void DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStruct;
  NVIC_InitTypeDef NVIC_InitStructure;
 
  // TIM4_UP - DMA1, Channel 2, Stream 6
 
  DMA_InitStruct.DMA_Channel            = DMA_Channel_2;
  DMA_InitStruct.DMA_BufferSize         = PWM_ELEMENTS;
  DMA_InitStruct.DMA_DIR                = DMA_DIR_MemoryToPeripheral;
  DMA_InitStruct.DMA_Mode               = DMA_Mode_Circular;
  DMA_InitStruct.DMA_FIFOMode           = DMA_FIFOMode_Disable;
  DMA_InitStruct.DMA_FIFOThreshold      = DMA_FIFOThreshold_HalfFull;
  DMA_InitStruct.DMA_Memory0BaseAddr    = (uint32_t)&PWM_Buffer[0];
  DMA_InitStruct.DMA_MemoryBurst        = DMA_MemoryBurst_Single;
  DMA_InitStruct.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
  DMA_InitStruct.DMA_MemoryInc          = DMA_MemoryInc_Enable;
  DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&TIM4->CCR1;
  DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStruct.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
  DMA_InitStruct.DMA_Priority           = DMA_Priority_Medium;
 
  DMA_Init(DMA1_Stream6, &DMA_InitStruct);

  // Disable stream
  DMA_Cmd(DMA1_Stream6, DISABLE);

  // Configure double DMA mode.
  // This function can be called only when the DMA Stream is disabled.

  DMA_DoubleBufferModeConfig(DMA1_Stream6,(uint32_t)&PWM_Buffer2[0],DMA_Memory_0);

  // Enable DMA double mode. This function can be called only when the DMA Stream is disabled.
  DMA_DoubleBufferModeCmd(DMA1_Stream6, ENABLE);

  //!Enable DMA transfer complete interrupt
  DMA_ITConfig(DMA1_Stream6, DMA_IT_TC, ENABLE);
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream6_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  NVIC_EnableIRQ(DMA1_Stream6_IRQn);

  // turning DMA on
  DMA_Cmd(DMA1_Stream6, ENABLE);
}


// Interrupt handler for dma transfer 1/2 finished, i.e after one buffer done.

void DMA1_Stream6_IRQHandler(void) {
    // Stream6 transfer complete interrupt?
    if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_TCIF6)) {     // Transfer Complete event
        // clear pending interrupt
        DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6);

        if(DMA_GetCurrentMemoryTarget(DMA1_Stream6)) {
        }
        else{
        }
    }
}

-----------------------------------------------------------------

Can anyone help?

EDIT: This is on a STM32F4Discovery Board

Outcomes