Skip to main content
Tobe
Senior III
April 9, 2024
Solved

Timer input capture interrupt fires over and over - Not a late flag reset issue (probably)

My input capture interrupt is fired over and over again. But when i put a breakpoint in the interrupt, and resume from it, it does not happen anymore.

Timer setup:

 

 

	// TIM 3 Inputs (Pedal rot - PB5 / Torc PWM - PB1)
	my_GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_1;
	my_GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	my_GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(GPIOB, &my_GPIO_InitStruct);
	GPIOB->AFR[0] |= (	GPIO_AFRL_AFSEL1_1 | 	// AF2 (all)
						GPIO_AFRL_AFSEL5_1);
	__disable_irq();
	__HAL_RCC_TIM3_CLK_ENABLE();

	SET_BIT( TIM3->CCMR1, TIM_CCMR1_CC2S_0);
	SET_BIT( TIM3->CCMR2, 	TIM_CCMR2_CC4S_0);	// channel is configured as input, tim_ic1 is mapped on tim_ti1, etc...
	// TODO: filter??
	SET_BIT( TIM3->CCER, TIM_CCER_CC2E |
							TIM_CCER_CC2NP |
							TIM_CCER_CC2P |
							TIM_CCER_CC4E |
							TIM_CCER_CC4NP |
							TIM_CCER_CC4P);		// capture enable and Rising and falling edge

	// TISEL default input channels

	SET_BIT( TIM3->DIER, TIM_DIER_CC2IE | TIM_DIER_CC4IE); 	// enable interrupt on signal
	SET_BIT( TIM3->CR1, TIM_CR1_CEN); 		// enable counter timer 3

	NVIC_EnableIRQ(TIM3_IRQn);				// enable global interrupt
	SET_BIT(TIM3->EGR, TIM_EGR_CC2G);	//force interrupt
	__enable_irq();

 

 

 

Interrupt:

 

void TIM3_IRQHandler(){
	GPIOC->BSRR = (uint32_t) GPIO_PIN_3;
	if(READ_BIT(TIM3->SR, TIM_SR_CC4IF)){	// Torc PWM interrupt on CH4
		unsigned long captValue = TIM3->CCR4;	// read Capture register (resets interrupt flag)
		unsigned long lastRisingEdge = 0;
		unsigned long lastFallingEdge = 0;

		if(READ_BIT(GPIOB->IDR, GPIO_PIN_1)){	// Rising edge
			pwmDuty = (lastFallingEdge - lastRisingEdge) / (captValue - lastRisingEdge);
			lastRisingEdge = captValue;
		}
		else{	// Falling edge
			lastFallingEdge = captValue;
		}
	}

//	if(READ_BIT(TIM3->SR, TIM_SR_CC2IF)){	// Pedal rotation
//
//
//	}


	SET_BIT(TIM3->SR, 0xFFFFFFFF);//TIM_SR_CC2IF | TIM_SR_CC4IF); 	// Clear any int flags
	delayMicroseconds(1);
	GPIOC->BRR = (uint32_t) GPIO_PIN_3;
}

 

 

.I checked the pin, which is not floating nor receiving any relevant noise.

This topic has been closed for replies.
waclawek.jan
waclawek.janBest answer
Super User
April 9, 2024

TIMx_SR bits are cleared by writing 0 to them, not 1.

JW

10 replies

AScha.3
Super User
April 9, 2024

Maybe - you just need little delay in INT... read:

http://www.efton.sk/STM32/gotcha/g7.html

 

If you feel a post has answered your question, please click on " Best Answer ".
Tobe
TobeAuthor
Senior III
April 9, 2024

I was thinking about what i did wrong the last time i had such issue. Alltough i am almost doing exactly the same thing, that could lead to this cause, it is not the cause with the current issue.

I added 1us delay after the reset of the flags, and it stil does not help.

 

Tobe
TobeAuthor
Senior III
April 9, 2024

Interesting:

If i let the pins setup as outputs, the interrupt is still fired.

Tobe
TobeAuthor
Senior III
April 9, 2024

This is now the minimum setup, with which i can provoke the error:

 

	__HAL_RCC_TIM3_CLK_ENABLE();

	SET_BIT( TIM3->DIER, TIM_DIER_CC2IE | TIM_DIER_CC4IE); 	// enable interrupt on signal
	SET_BIT( TIM3->CR1, TIM_CR1_CEN); 		// enable counter timer 3

	NVIC_EnableIRQ(TIM3_IRQn);				// enable global interrupt

 

BUT this time, the problem persists after hitting resume!

Tobe
TobeAuthor
Senior III
April 9, 2024

After a few more tries i think it has something to do with

 

SET_BIT(TIM3->EGR, TIM_EGR_CC2G);	//force interrupt

 

The repeated execution of the interrupt happens every time the interrupt is forced. But still it after resuming in debug, the problem dissappears.

 

Without forcing the interrupt, there is no issue!

Tobe
TobeAuthor
Senior III
April 9, 2024

These are the registers just before the force of the interrupt, and at the beginning of the interrupt:

 

waclawek.jan
waclawek.janBest answer
Super User
April 9, 2024

TIMx_SR bits are cleared by writing 0 to them, not 1.

JW

Tesla DeLorean
Guru
April 9, 2024

+1 This

 

if (TIM3->SR & TIM_SR_CC4IF){ // Torc PWM interrupt on CH4
 ...
 TIM3->SR = ~TIM_SR_CC4IF; // Send the inverse pattern, DO NOT RMW with AND
 ...

}

 

Do it reasonably early too, so the TIM/NVIC has a chance to clear prior to tail-chaining on exit

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..