2024-04-09 10:55 AM - edited 2024-04-09 09:36 PM
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.
Solved! Go to Solution.
2024-04-09 03:10 PM
2024-04-09 11:26 AM
Maybe - you just need little delay in INT... read:
http://www.efton.sk/STM32/gotcha/g7.html
2024-04-09 12:02 PM
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.
2024-04-09 12:10 PM
I have edited the post, as it now also happens without the other interrupt setup.
2024-04-09 12:44 PM
Interesting:
If i let the pins setup as outputs, the interrupt is still fired.
2024-04-09 12:51 PM - edited 2024-04-09 12:52 PM
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!
2024-04-09 01:39 PM - edited 2024-04-09 01:43 PM
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!
2024-04-09 02:19 PM
2024-04-09 03:10 PM
TIMx_SR bits are cleared by writing 0 to them, not 1.
JW
2024-04-09 03:51 PM - edited 2024-04-09 03:54 PM
+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