Skip to main content
Beartama
Associate II
August 19, 2025
Solved

Setting IFCR does not clear ISR

  • August 19, 2025
  • 3 replies
  • 543 views

I'm using the STM32F103C8T6, and trying to blink my LED via the interrupt handler of a DMA with this code

#include <stdint.h>
// STM32F103C8 is a medium density device, hence we use the xB header
#include <stm32f103xb.h>

#if !defined(__SOFT_FP__) && defined(__ARM_FP)
#warning \
 "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif

int main(void) {
	uint32_t blinking[2] = { GPIO_BSRR_BR8, GPIO_BSRR_BS8 };
	uint32_t dest = 0;

	RCC->CR |= RCC_CR_HSION;
	while ((RCC->CR & RCC_CR_HSIRDY) == 0)
		;

	RCC->AHBENR |= RCC_AHBENR_DMA1EN; // Enable clock for DMA1
	RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // Enable clock for TIM1
	RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Enable IO port A

	NVIC_EnableIRQ(DMA1_Channel2_IRQn);

	DMA1_Channel2->CCR |= DMA_CCR_MSIZE_1 // 32-bits memory size
	| DMA_CCR_PSIZE_1 // 32-bits peripheral size
			| DMA_CCR_MINC // Memory increment
			| DMA_CCR_CIRC // Circular mode
			| DMA_CCR_DIR // Read from memory
			| DMA_CCR_HTIE // Enable half transfer interrupt
			| DMA_CCR_TCIE // Enable complete interrupt
			| DMA_CCR_MEM2MEM
	;

	DMA1_Channel2->CNDTR = 2;
// DMA1_Channel2->CPAR = (uint32_t)&GPIOA->BSRR;
	DMA1_Channel2->CPAR = (uint32_t) &dest;
	DMA1_Channel2->CMAR = (uint32_t) blinking;

	TIM1->CCMR1 |= TIM_CCMR1_OC1M_0;
	TIM1->DIER |= TIM_DIER_CC1DE;
	TIM1->CCER |= TIM_CCER_CC1E; // Enable OC1 output
	TIM1->BDTR |= TIM_BDTR_MOE;

	TIM1->PSC = 512 - 1;
	TIM1->ARR = (15625 * 2) - 1;

	GPIOA->CRH &= ~(GPIO_CRH_CNF8 | GPIO_CRH_MODE8); // GPIO A: Clear pin 8 configuanaration
	GPIOA->CRH |=
	GPIO_CRH_MODE8; // GPIO A: Set pin 8 to output with 50 MHz and push-pull

	DMA1_Channel2->CCR |= DMA_CCR_EN;
	TIM1->CR1 |= TIM_CR1_CEN;

	/* Loop forever */
	for (;;) {
	}
}

void DMA1_Channel2_IRQHandler() {
	if ((DMA1->ISR & DMA_ISR_HTIF2) != 0) {
		GPIOA->BSRR = GPIO_BSRR_BR8;
	}
	if ((DMA1->ISR & DMA_ISR_TCIF2) != 0) {
		GPIOA->BSRR = GPIO_BSRR_BS8;
	}

	DMA1->IFCR = DMA_IFCR_CGIF2 | DMA_IFCR_CHTIF2 | DMA_IFCR_CTCIF2;
}

However, at 67, setting the IFCR register does not seem to clear the ISR flags and the handler keeps getting called. How do I handle this?

 

Best answer by waclawek.jan

How do you know?

[EDIT]

DMA_CCR_MEM2MEM

Don't. This does not do what you may think it does. The M2M mode means "ignore trigger from TIM, do autotrigger the given channel so that transfers run as quick as possible".

JW

3 replies

TDK
Super User
August 19, 2025

> DMA_CCR_CIRC // Circular mode

> the handler keeps getting called

Seems like correct behavior to me.

Use normal (non-circular) mode if you only want it to happen once.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Beartama
BeartamaAuthor
Associate II
August 19, 2025

I mean the handler is called immediately without the delay expected.

waclawek.jan
waclawek.janBest answer
Super User
August 19, 2025

How do you know?

[EDIT]

DMA_CCR_MEM2MEM

Don't. This does not do what you may think it does. The M2M mode means "ignore trigger from TIM, do autotrigger the given channel so that transfers run as quick as possible".

JW

Beartama
BeartamaAuthor
Associate II
August 19, 2025

My setup has an LED connected to GPIO A8, if there’s a delay between two interruption invocations, i would see the LED blinking. However, I see the LED stays bright without being turned off.

TDK
Super User
August 19, 2025

Can your eyes detect if it's blinking at 1 MHz? Unlikely.

The flag is getting cleared here, it's just getting set again immediately afterwards because the transfer happens so fast.

"If you feel a post has answered your question, please click ""Accept as Solution""."
waclawek.jan
Super User
August 19, 2025

Yes, I repeat, don't use MEM2MEM in DMA, as it ignores the triggers from timer and autotriggers at maximum rate.

JW

Beartama
BeartamaAuthor
Associate II
August 19, 2025

Yes, I just saw your edit, this was problem. Thank you very much.