I'm working with a Cortex M4 (Freescale's Freedom-K64F dev-board). I'm trying to write a long sequence of data to flash. The state machine for this sequence operates in the interrupt handler. This means that in the handler for the processor's flash-controller interrupt, I launch further flash controller operations. The last of my sequence of data operations is short, and is likely to finish very quickly. Launching a successive flash operation from a IRQ handler means that it is possible (in some cases such as the last operation) for the `successive` operation to complete before the IRQ-handler which launched it; and in fact I do see this happening. The problem is that such a sequence where a an active interrupt is made active_and_pending from an internal peripheral seems to not be working reliably for me. I find that the `active and pending state` does not restart the interrupt handler automatically upon return from the handler.
My application fails to field a successive interrupt when a `successive` operation launched from an active interrupt handler completes early. The only way I have been able to reason about it is by arguing that returning from an interrupt clears the pending flag and therefore causes my application to miss pending IRQ-handling.
To support my hypothesis further, I've re-written my IRQ handler in the following fashion:
void IRQ_Handler(void)
{
do {
handleCompletedOperationsAndProgressStateMachine();
} while (NVIC_GetPendingIRQ(...) != 0);
}
This does help, but there is still a small window between while (NVIC_GetPendingIRQ(...) != 0); and the actual return of the IRQ where the interrupt could be set as pending again and be lost.
Is it a processor-implementation thing that the pending status of an interrupt is cleared upon interrupt return?
It is almost as if the flash controller though the interrupt was edge triggered but the interrupt controller though it was level sensitive and managed to interrupt the controller always when it wasn't actually handling the interrupt. The other option I can see is that there is some software lurking in the interrupt handler which does a software acknowledge of the interrupt. Neither seems very likely so I'm a bit stumped. It would be interesting to put a delay between the handleCompletedOperationsAndProgressStateMachine() and the while (NVIC_GetPendingIRQ(...) != 0) to see if the next interrupt disappears in between. This would tell you it has nothing to do with the return and the interrupt is level triggered. And it would still leave me wondering why the level is dropped.
The fault lay in my software. I had set PRIMASK by accident during the state machine.
Sorry I hadn't noticed your reply, and thanks. That certainly explains things and shows there's always some other good explanation.
I am glad you solved the problem.
Yasuhiko Koumoto.