This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

DMA IRQHandler not working

When I run this code I don't get into the DMA IQRHandler. I am trying to put the signal, generated in the main, on the DAC output using the DMA. Haven't got any luck so far. Been searching on this problem all day.
Any help?

/******************************************************************

Author:         Bert Vanoverschelde
Revision: v1.0
Summary:        DAC/DMA test
Date:                   21/05/2015

******************************************************************/

/*INCLUDES*/
#include "stm32f10x_rcc.h"              // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_tim.h"              // Keil::Device:StdPeriph Drivers:TIM
#include "stm32f10x_dac.h"              // Keil::Device:StdPeriph Drivers:DAC
#include "stm32f10x_dma.h"              // Keil::Device:StdPeriph Drivers:DMA
#include "stm32f10x_gpio.h"             // Keil::Device:StdPeriph Drivers:GPIO
#include "LED.h"                        // Keil.MCBSTM32C::Board Support:MCBSTM32C:LED
#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include "cmsis_os.h"                   // ARM::CMSIS:RTOS:Keil RTX

#define PERIOD 1152
/*GLOBAL VARIABLES*/
uint8_t waveform[256];

void GPIO_Setup(){
        GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable DAC and GPIOC clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);

  /* Configure PA.04/05 (DAC) as output -------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}


void Timer_Setup(){
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* TIM2 Configuration */
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Period = PERIOD;
  TIM_TimeBaseStructure.TIM_Prescaler = 0xF;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  /* TIM2 TRGO selection */
  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_OC1Ref);

}

void DAC_Setup(){
        DAC_InitTypeDef DAC_InitStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

          /* DAC channel1 Configuration */
  DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
  DAC_Init(DAC_Channel_2, &DAC_InitStructure);

  /* Enable DAC Channel2: Once the DAC channel2 is enabled, PA.05 is
     automatically connected to the DAC converter. */
  DAC_Cmd(DAC_Channel_2, ENABLE);
}

void DMA_Setup(){
        DMA_InitTypeDef DMA_InitStructure;
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

        /* DMA 1 Configuration */
        DMA_DeInit(DMA1_Channel7);
        DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR8R1_DACC1DHR;
        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)waveform;
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
        DMA_InitStructure.DMA_BufferSize = 256;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

        DMA_Init(DMA1_Channel7, &DMA_InitStructure);
        DMA_ITConfig(DMA1_Channel7, DMA_IT_HT | DMA_IT_TC | DMA_IT_TE, ENABLE);



        DMA_Cmd(DMA1_Channel7, ENABLE);
}

void DMA1_Channel7_IRQHandler(){
        LED_On(1);
        DMA_ClearITPendingBit(DMA1_IT_GL7);



}

void NVIC_Setup(){
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_Init(&NVIC_InitStructure);
}


int main(void){
                uint16_t i, x;
        for (i = 0; i < 256; i++) {
                if (i < 10) {
                        x = 10;
                } else if (i < 121) {
                        x = 10 + ((i*i) >> 7);
                } else if (i < 170) {
                        x = i/2;
                } else if (i < 246) {
                        x = i + (80 - i/2);
                } else {
                        x = 10;
                }
                waveform[i] = x;
        }

        GPIO_Setup();
        Timer_Setup();
        NVIC_Setup();
        DMA_Setup();
        DAC_Setup();
        LED_Initialize();


  while (1)
  {
                                int i;
                                LED_On(0);


        //for(i=0; i<4096; i++)
        //  DAC_SetChannel2Data(DAC_Align_12b_R, i);
                                //LED_Off(0);
  }

  return(1);
}

  • It's not getting to the IRQ because you're not triggering any DMA transfers. The TIM settings have no relationship to the desired triggering of the DMA.

    The RM0008 Reference Manual might prove more useful than Google.

  • OK so I came to the conclusion that I was using the wrong DMA channel, and that there was a timer practically dedicated for the DAC. Still the main problem persists, I can't enter in the IRQHandler. The DMA and DAC are working fine now.

    /* Includes ------------------------------------------------------------------*/
    #include "stm32f10x.h"
    #include "LED.h"
    
    /* Private typedef -----------------------------------------------------------*/
    /* Private define ------------------------------------------------------------*/
    
    /* Init Structure definition */
    DAC_InitTypeDef            DAC_InitStructure;
    DMA_InitTypeDef            DMA_InitStructure;
    NVIC_InitTypeDef                                         NVIC_InitStructure;
    
    /* Private macro -------------------------------------------------------------*/
    /* Private variables ---------------------------------------------------------*/
    uint8_t Escalator8bit[256];
    
    /* Private functions ---------------------------------------------------------*/
    
    void RCC_Configuration(void)
    {
      /* Enable peripheral clocks ------------------------------------------------*/
    #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL
      /* DMA2 clock enable */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
    #else
      /* DMA1 clock enable */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    #endif
      /* GPIOA Periph clock enable */
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
      /* DAC Periph clock enable */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
      /* TIM6 Periph clock enable */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
    }
    
    void GPIO_Configuration(void)
    {
      GPIO_InitTypeDef GPIO_InitStructure;
    
      /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically
         connected to the DAC converter. In order to avoid parasitic consumption,
         the GPIO pin should be configured in analog */
      GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
    }
    
    void TIMER_Configuration(){
      /* TIM6 Configuration */
      TIM_PrescalerConfig(TIM6, 0xF, TIM_PSCReloadMode_Update);
      TIM_SetAutoreload(TIM6, 0xFF);
      /* TIM6 TRGO selection */
      TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
    }
    
    void DAC_Configuration(){
      /* DAC channel1 Configuration */
      DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
      DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
      DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
      DAC_Init(DAC_Channel_1, &DAC_InitStructure);
    }
    
    void DMA_Configuration(){
    #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL
      /* DMA2 channel3 configuration */
      DMA_DeInit(DMA2_Channel3);
    #else
      /* DMA1 channel3 configuration */
      DMA_DeInit(DMA1_Channel3);
    #endif
    
      DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR8R1;
      DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Escalator8bit;
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
      DMA_InitStructure.DMA_BufferSize = 256;
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
      DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
      DMA_InitStructure.DMA_Priority = DMA_Priority_High;
      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    
    #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL
      DMA_Init(DMA2_Channel3, &DMA_InitStructure);
      /* Enable DMA2 Channel3 */
      DMA_Cmd(DMA2_Channel3, ENABLE);
    #else
      DMA_Init(DMA1_Channel3, &DMA_InitStructure);
      /* Enable DMA1 Channel3 */
      DMA_Cmd(DMA1_Channel3, ENABLE);
    #endif
    
      DMA_ITConfig(DMA1_Channel3 , DMA_IT_TC | DMA_IT_HT , ENABLE);
    }
    
    void NVIC_Configuration(){
       //Enable DMA1 channel IRQ Channel
       NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
       NVIC_Init(&NVIC_InitStructure);
    }
    
    void DMA1_Channel3_IRQHandler(void){
       LED_On(0);
       if(DMA_GetITStatus(DMA1_IT_TC3))
      {
          LED_On(1);
       //Clear DMA1 Channel1 Half Transfer, Transfer Complete and Global interrupt pending bits
        DMA_ClearITPendingBit(DMA1_IT_GL3);
      }
    }
    
    int main(void)
    {
                    int i;
                    for(i=0; i<256; i++){
                            Escalator8bit[i] = i;
                    }
      /*!< At this stage the microcontroller clock setting is already configured,
           this is done through SystemInit() function which is called from startup
           file (startup_stm32f10x_xx.s) before to branch to application main.
           To reconfigure the default setting of SystemInit() function, refer to
           system_stm32f10x.c file
         */
    
      /* System Clocks Configuration */
      RCC_Configuration();
            LED_Initialize();
      /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically
         connected to the DAC converter. In order to avoid parasitic consumption,
         the GPIO pin should be configured in analog */
      GPIO_Configuration();
            TIMER_Configuration();
            DAC_Configuration();
            DMA_Configuration();
            NVIC_Configuration();
      /* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is
         automatically connected to the DAC converter. */
      DAC_Cmd(DAC_Channel_1, ENABLE);
      /* Enable DMA for DAC Channel1 */
      DAC_DMACmd(DAC_Channel_1, ENABLE);
      /* TIM6 enable counter */
      TIM_Cmd(TIM6, ENABLE);
            LED_On(2);
      while (1)
      {
      }
    }
    

  • Pretty sure it needs to be DMA2_Channel3. See RM0008 Rev15

    Don't enable the HT interrupt unless you plan to service it.

    And if you're using C++ (.cpp) then

    extern "C" void DMA2_Channel3_IRQHandler(void)
    {
    ..
    }
    

  • OK indeed! thanks a lot for your help!