Timer input capture interrupt fires over and over - Not a late flag reset issue (probably)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-09 10:55 AM - edited ‎2024-04-09 9: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.
- Labels:
-
STM32G4 Series
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-09 3:10 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-09 11:26 AM
Maybe - you just need little delay in INT... read:
http://www.efton.sk/STM32/gotcha/g7.html
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-09 12:10 PM
I have edited the post, as it now also happens without the other interrupt setup.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-09 12:44 PM
Interesting:
If i let the pins setup as outputs, the interrupt is still fired.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-09 1:39 PM - edited ‎2024-04-09 1: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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-09 2:19 PM
These are the registers just before the force of the interrupt, and at the beginning of the interrupt:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-09 3:10 PM
TIMx_SR bits are cleared by writing 0 to them, not 1.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-09 3:51 PM - edited ‎2024-04-09 3: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
Up vote any posts that you find helpful, it shows what's working..
