2013-10-21 01:26 AM
Hello again,
I have learned that this:void DMA2_Stream3_IRQHandler()
{
// Test if DMA Stream Transfer Complete interrupt
if (DMA_GetITStatus(DMA2_Stream3, DMA_IT_TCIF3))
{
DMA_ClearITPendingBit(DMA2_Stream3, DMA_IT_TCIF3);
}
}
is danger on a Cortex-M3/4. The Interrupt can be reentered immediately due to some pipline issues. Is it enough to insert two nops to clear this situation?
void DMA2_Stream3_IRQHandler()
{
// Test if DMA Stream Transfer Complete interrupt
if (DMA_GetITStatus(DMA2_Stream3, DMA_IT_TCIF3))
{
DMA_ClearITPendingBit(DMA2_Stream3, DMA_IT_TCIF3);
}
__NOP();
__NOP();
}
Currently it works for me, but does it work under all situations?
Martin
2013-10-21 05:32 AM
What is the point of such a routine? If you do any read/write on memory it will fence the interrupt clearing write. So increment a variable, write a flag, anything should be sufficient.
https://community.st.com/0D50X00009XkYyUSAV
https://community.st.com/0D50X00009XkZ4PSAV
Edit: Fixed DEAD LINKs, original post from Oct 21, 2013
2013-10-21 07:39 AM
Hi Clive,
These where dummies, so i can't forget one and i can keep die handler happy while coding and testing. These costs me a few hours of debugging for nothing before i found my fault :)Maybe a big TODO comment, these nops or a __DMB() is better in future (it seems that Keil-C is able to optimize nop() avay on higher optimization settings)Martin2013-10-21 07:47 AM
Writing or incrementing a volatile variable should be quite adequate to force in-order completion.
volatile int jiffies;
void DMA2_Stream3_IRQHandler()
{
// Test if DMA Stream Transfer Complete interrupt
if (DMA_GetITStatus(DMA2_Stream3, DMA_IT_TCIF3)) // Qualify
{
DMA_ClearITPendingBit(DMA2_Stream3, DMA_IT_TCIF3); // Clear Early
// Do something
jiffies++;
}
}