AnsweredAssumed Answered

STM32F4xx DMA IRQ problem

Question asked by lombardini.luca on Jun 4, 2012
Latest reply on Nov 16, 2016 by w.johan
Hi all,

I'm using the STM Discovery EVM to make some sample program.
I'm using IAR as compiler and CMSIS 2.1
In this example I simple set a timer with 50ms period and start DMA transfert on USART 3
The transfer is correctly done on the serial port (I see the transmitted sting using Hyperterminal on PC), but I have a problem on the DMA IRQ Handler routine,
Infact when I check the TCIF flag I found that the DMA transfert is not complete (while the transfert is already done on serial port). Furthermore I check for any DMA tranfert error and I found that there are no error. Where I wrong?

Here The revelant part of the code:
First the define for DMA

/* Definition for DMAx resources **********************************************/
#define USARTx_DR_ADDRESS                ((uint32_t)USART3 + 0x04)

#define USARTx_DMA                       DMA1
#define USARTx_DMAx_CLK                  RCC_AHB1Periph_DMA1
   
#define USARTx_TX_DMA_CHANNEL            DMA_Channel_4
#define USARTx_TX_DMA_STREAM             DMA1_Stream3
#define USARTx_TX_DMA_FLAG_FEIF          DMA_FLAG_FEIF3
#define USARTx_TX_DMA_FLAG_DMEIF         DMA_FLAG_DMEIF3
#define USARTx_TX_DMA_FLAG_TEIF          DMA_FLAG_TEIF3
#define USARTx_TX_DMA_FLAG_HTIF          DMA_FLAG_HTIF3
#define USARTx_TX_DMA_FLAG_TCIF          DMA_FLAG_TCIF3
            
#define USARTx_RX_DMA_CHANNEL            DMA_Channel_4
#define USARTx_RX_DMA_STREAM             DMA1_Stream1
#define USARTx_RX_DMA_FLAG_FEIF          DMA_FLAG_FEIF1
#define USARTx_RX_DMA_FLAG_DMEIF         DMA_FLAG_DMEIF1
#define USARTx_RX_DMA_FLAG_TEIF          DMA_FLAG_TEIF1
#define USARTx_RX_DMA_FLAG_HTIF          DMA_FLAG_HTIF1
#define USARTx_RX_DMA_FLAG_TCIF          DMA_FLAG_TCIF1

#define USARTx_DMA_TX_IRQn               DMA1_Stream3_IRQn
#define USARTx_DMA_RX_IRQn               DMA1_Stream1_IRQn
#define USARTx_DMA_TX_IRQHandler         DMA1_Stream3_IRQHandler
#define USARTx_DMA_RX_IRQHandler         DMA1_Stream1_IRQHandler   

here the TX Buffer String
uint8_t TxBuffer[]= "^**********************************************************************\r\n\
Prova di invio di caratteri alla seriale per vedere se ne perde qualcuno\r\n\
Cosi vediamo come si comporta il uP e il PC sperando che entrambi ce la facciano\r\n\
**********************************************************************@";


Then the Timer IRQ Handler routine:
void TIM3_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);

    /* LED4 toggling with frequency = 4.57 Hz */
    STM_EVAL_LEDToggle(LED4);
    capture = TIM_GetCapture1(TIM3);
    TIM_SetCompare1(TIM3, capture + CCR1_Val);
    if (!DMASet)
       SetDMA();
    STM_EVAL_LEDToggle(LED4);
  }
}

Here MY routine for DMA settings
void SetDMA(void)
{
    DMASet = 1;
    DMA_DeInit(USARTx_TX_DMA_STREAM);
    DMA_InitStructureTX.DMA_PeripheralBaseAddr = USARTx_DR_ADDRESS;
    DMA_InitStructureTX.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructureTX.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructureTX.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructureTX.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructureTX.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructureTX.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructureTX.DMA_FIFOMode = DMA_FIFOMode_Enable;
    DMA_InitStructureTX.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructureTX.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructureTX.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_InitStructureTX.DMA_Channel = USARTx_TX_DMA_CHANNEL;
    DMA_InitStructureTX.DMA_DIR = DMA_DIR_MemoryToPeripheral;  
    DMA_InitStructureTX.DMA_Memory0BaseAddr = (uint32_t)TxBuffer;
//    DMA_InitStructureTX.DMA_BufferSize = 300;
    DMA_InitStructureTX.DMA_BufferSize = 300;
//    DMA_InitStructureTX.DMA_BufferSize = (uint16_t)BUFFERSIZE;
    DMA_Init(USARTx_TX_DMA_STREAM, &DMA_InitStructureTX);

    /* Enable DMA1_Stream3 Transfer complete interrupt */
    DMA_ITConfig(USARTx_TX_DMA_STREAM, DMA_IT_TC, ENABLE);
    
//    /* Enable DMA1_Stream3 */
//    DMA_Cmd(USARTx_TX_DMA_STREAM, ENABLE);
//      
      
      /* Enable DMA USART Tx Stream */
      DMA_Cmd(USARTx_TX_DMA_STREAM, ENABLE);
}

At the end the DMA IRQ Handler routine

void DMA1_Stream3_IRQHandler(void)
{
//  STM_EVAL_LEDToggle(LED6);
  if(DMA_GetITStatus(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_TCIF))
  {
    DMA_ClearITPendingBit(DMA1_Stream3, DMA_IT_TCIF3);

//    /* Clear all DMA Streams flags */
////    DMA_ClearFlag(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_HTIF | USARTx_TX_DMA_FLAG_TCIF);
//    DMA_ClearFlag(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_TCIF);
//                                          
//    /* Disable the DMA Stream */
//    DMA_Cmd(USARTx_TX_DMA_STREAM, DISABLE);
//      
//    /* Disable the USART Tx DMA request */
//    USART_DMACmd(USARTx, USART_DMAReq_Tx, DISABLE);

      STM_EVAL_LEDToggle(LED6);
   }
  if (DMA_GetITStatus(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_TEIF))
    STM_EVAL_LEDToggle(LED6);
  if (DMA_GetITStatus(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_HTIF))
    STM_EVAL_LEDToggle(LED6);
  if (DMA_GetITStatus(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_FEIF))
    STM_EVAL_LEDToggle(LED6);
 
}



Outcomes