2024-11-10 11:25 AM
I have quite a complicated case, where a interrupt is beeing executed, allthough it has been disabled, and its flag beeing cleared. At the same time interrupts are disabled, and i put a few nops in between just to rule out any delay related issues. The disabling of the interrupt works, but there is just one afterwards that i cant get rid of.
For now i just would like to know, if anyone has any idea if the title can be answered with yes. (And if there is a explanation why that is)
I would have liked to try a minimal code, but its quite complicated and i am afraid the error can then not be reproduced. Timers are interconnected too.
2024-11-10 11:44 AM
If you disable the interrupt at the source (e.g. in TIMx_DIERx), it takes time until this gets propagated into NVIC.
There may be a strange effect with the interrupt "reappearing" in NVIC, if it was cleared too soon after disabling the interrupt source.
JW
2024-11-10 12:17 PM
This is how i clear it:
CLEAR_BIT(TIM8->DIER, TIM_DIER_CC4IE);
30 NOP´s
TIM8->SR = ~TIM_SR_CC4IF;
30 NOP´s
other code
SET_BIT(TIM8->EGR, TIM_EGR_COMG); //should not matter here
delayMicros(2);
When i enable interrupts before the delay, the interrupt does not get fired again, if i enable interrupts after, it does get fired again. See the picture for timing illusatration:
2024-11-10 12:48 PM
There is no direct relationship between commutation event and CC4 event, so it can't be judged from this description without knowing your entire program.
JW
2024-11-10 01:14 PM
Any ideas what i could look into? What registers, or what tactic could be done?
What about the enabling of interruts, why does it make a difference of when the are enabled?
2024-11-10 02:15 PM - edited 2024-11-10 02:42 PM
Allthough your link is not the exact problem i have (i think), it helped me (reading pending states) to get further: clearing the TIM_SR_CC4IF flag did not clear the pending interrupt, i had to clear the pending interrupt too.
Is this something that has to be done in general? I did not stumble upon this issue yet with my other interrupts.
2024-11-11 01:42 AM - edited 2024-11-11 01:44 AM
I have now finished my investigation:
It is, as i expected, and wrote in the title of this topic:
In order for the pending status to be cleared with clearing the TIM_SR_CC4IF flag, interrupts have to be enabled at the same time. This also applies to reading the TIM_SR_CC4IF register.
That is NOT something i would expect. Usually i would disable interrupts, and then clear flags, to have a clean state of my program.
NOTE: It is necessary to have enabled interrupts in general, AND the CC interrupt itself, in order for the reading and clearing of the CC4IF flag to work properly!
I went down the rabbit hole, and i was there for quite a few days...
Huge thanks @waclawek.jan for pushing me into the right track, and using the array to debug the pending state!
Here the code as it was last used by me:
//__enable_irq();
//while(READ_BIT(TIM8->SR, TIM_SR_CC4IF)); // Wait for flag to cause issue //TODO: Debug remove
//IRQ_DISABLE_SAVE_PREV
NVIC_EnableIRQ(TIM8_CC_IRQn);
SEVEN_NOPS
stateArray[2] = NVIC_GetPendingIRQ(TIM8_CC_IRQn);
TEST_CLEAR_TIM8_CC4_IRQ_DIS_ON
CLEAR_BIT(TIM8->DIER, TIM_DIER_CC4IE); // Disable interrupts (from ADC trigger) for kind of sine wave generation
SEVEN_NOPS
stateArray[3] = NVIC_GetPendingIRQ(TIM8_CC_IRQn);
TIM8->SR = ~TIM_SR_CC4IF; // Clear any pending interrupts that were already pending.
stateArray[4] = NVIC_GetPendingIRQ(TIM8_CC_IRQn);
SEVEN_NOPS
stateArray[5] = NVIC_GetPendingIRQ(TIM8_CC_IRQn);
// NVIC_ClearPendingIRQ(TIM8_CC_IRQn);
//
// stateArray[6] = NVIC_GetPendingIRQ(TIM8_CC_IRQn);
// SEVEN_NOPS // Account for delay, that a signal could arrive after clearing the pending interrupt.
stateArray[7] = NVIC_GetPendingIRQ(TIM8_CC_IRQn);
if(millis() > 100)
stopNow = true;
updateDuty();
delayMicroseconds(6); // delay and test if interrupt cleared
TEST_CLEAR_TIM8_CC4_IRQ_DIS_OFF
//__enable_irq();
NVIC_EnableIRQ(TIM8_CC_IRQn);
stateArray[8] = NVIC_GetPendingIRQ(TIM8_CC_IRQn);