Skip to main content
Graduate
April 9, 2024
Solved

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

  • April 9, 2024
  • 4 replies
  • 3132 views

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.
    Best answer by waclawek.jan

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

    JW

    4 replies

    Super User
    April 9, 2024

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

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

     

    TobeAuthor
    Graduate
    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.

     

    TobeAuthor
    Graduate
    April 9, 2024

    Interesting:

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

    TobeAuthor
    Graduate
    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!

    TobeAuthor
    Graduate
    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!

    TobeAuthor
    Graduate
    April 9, 2024

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

     

    Super User
    April 9, 2024

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

    JW

    Graduate II
    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