cancel
Showing results for 
Search instead for 
Did you mean: 

DMA interrupt not triggering after init

Klassic
Associate III

After setting configuration registers in HAL_DMA_Start_IT, DMA fails to fire back interrupt, HAL_DMA_IRQHandler(). The TransferComplete call back routine is not called but only once after reset since HAL_DMA_IRQHandler() is called only once after initialization. Flags CC1DE and CC1IE are set after initialization and never change there after. I am trying to read a parallel ADC through GPIO using DMA with interrupt and timer input capture. I am using STM32L496ZG ucontroller and used CUBEMX to generate code.

Also, I am using Timer2 with input capture mode to request DMA transfer. And using MCO to generate 2 MHz to feed to PA0 for timer2 ch1.

I searched the forum and checked almost everything. I used latest  CUBEMX 6.11.1 version.

Your help is greatly appreciated.
Thanks

Here is my initzn part;

 

 

 

 HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_DMA_Init();
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_USART2_UART_Init();
	if(DWT_Delay_Init())
	HAL_UART_Transmit(&huart2, (uint8_t *)"\r\nClkTick started", 17, HAL_MAX_DELAY);
	else
	HAL_UART_Transmit(&huart2, (uint8_t *)"\r\nClkTicks fail to start", 4, HAL_MAX_DELAY);

  /* USER CODE BEGIN 2 */
  if (HAL_DMA_Start_IT(htim2.hdma[TIM_DMA_ID_CC1], &GPIOE->IDR, (uint32_t)&aDST_Buffer, BUFFER_SIZE) != HAL_OK)
  {
    /* Transfer Error */
    Error_Handler();
  }

  // Attach DMA callback functions
  htim2.hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = HalfTransferComplete;
  htim2.hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TransferComplete;
  htim2.hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TransferError;

  // Enable timer to trigger DMA transfer - CC1DE bit
  __HAL_TIM_ENABLE_DMA(&htim2, TIM_DMA_CC1);
  // Enable timer input capture
  HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  }

 

 

Klassic_0-1718361144991.png           DMA Req setting: >Mode: Normal. 

 

 

 

And this is the data transfer callback routines:

 

 

 

static void HalfTransferComplete(DMA_HandleTypeDef *hdma_tim2_ch1) {
    int position = 0;
    LastITHalfComplete = 1;
    /*Copy the first part of the received buffer */
    for (int i = 0; i < HALF_BUFFER_SIZE; i++) {
        aFull_Buffer[FullDataIndex] = aDST_Buffer[i+position];
        FullDataIndex++;
        //HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_1);
    }
}
static void TransferComplete(DMA_HandleTypeDef *hdma_tim2_ch1)
{
    int position = HALF_BUFFER_SIZE;
    LastITHalfComplete = 0;

    /* Copy the second part of the received buffer */
    for (int i = 0; i < HALF_BUFFER_SIZE; i++) {
    aFull_Buffer[FullDataIndex] = aDST_Buffer[i+position];
        FullDataIndex++;
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
    }
    transferComplete = 1;
}

static void TransferError(DMA_HandleTypeDef *hdma_tim2_ch1) {
    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
}

 

 

 

6 REPLIES 6
SofLit
ST Employee

Hello,

As you need to transfer data from GPIO IDR to a memory, how did you configure the DMA? Peripheral to Memory? If yes this that's not the correct config.

You need to consider the GPIO register as a memory location so you need to configure it as Memory to Memory.

You can also refer to this application note AN4666.

Read also this post: https://community.st.com/t5/stm32-mcus-products/stm32f429-read-from-pin-to-dma/m-p/683278

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Thanks SofLit, 

As you know there's no Mem to Mem option available in recent cubeMx. Only Periph to Mem Or Mem to Periph. I read somewhere that Periph to Mem is same as Mem to Mem. plz correct me.

According to AN4666 doc, DMA1Ch5 was selected using Tim2Ch1. And I did the same.

For timer in Inp capture, I am using falling edge to trigger DMA.

 

Thanks

 

Hello,

How?

SofLit_0-1718368740655.png

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

I was checking here.

Klassic_0-1718370760388.png

Ok. But if I did be selecting DMA MEM to MEM directly without timer, then how to connect it to timer pulse trigger? I mean, what condition will trigger a DMA request? Which channel to choose along with DMA2?

 

Thanks 

 

Is the DMA set to Circular? If not, how do you start it again?

JW

Hi jan,

Sorry for late reply. I was working to put changes suggested by SofLit and DMA setting to circular, but could not succeed. DMA is set to normal.

Also, I could not accommodate MEM to MEM DMA change, as I could not connect interrupt trigger by timer with DMA.

  Still struggling to get it work.

Thanks