Part Number: TMS570LC4357
We've read over http://www.ti.com/lit/an/spna218/spna218.pdf and under the section "4.5.1 How Does it (Phantom Interrupts) Occur?" there is the text
" In this case, due to the imprecise timing of the VBUS write operation the interrupt service routine (ISR) could return before the CPU nIRQ or nFIQ interrupt request signal becomes inactive. ... When the peripheral interrupt pending flag is cleared by a read operation, the read instruction will return after at least 3 VBUS cycles and the CPU nIRQ or nFIQ interrupt request signal is already low when the interrupt service routine exits. Phantom interrupts will not occur in this situation."
My interpretation is that whenever we want to raise, clear, or mask an interrupt precisely we are guaranteed this will happen if we read back from the given register after writing it. But I'm not sure if memory barriers could accomplish the same thing because the given app note doesn't discuss them at all. For example here is simplified code we have for enabling an interrupt in the VIM:
// vimREG is volatile
void VimEnableInterrupt(uint32_t channel) {
vimREG->REQMASKSET[channel / 32] = (uint32_t)1U << (channel % 32);
(void)vimREG->REQMASKSET[channel / 32];
}
Note the readback at the end to guarantee that the write to vimREG will take effect by the end of this functions execution.
Would this code accomplish the same thing to guarantee that the write to vimREG will have taken effect by the end of the functions execution?
// vimREG is volatile
void VimEnableInterrupt(uint32_t channel) {
vimREG->REQMASKSET[channel / 32] = (uint32_t)1U << (channel % 32);
__asm__ __volatile__("dsb sy" ::: "memory");
}
I have a similar question about raising software interrupts. Currently we have the following code for raising a software interrupt:
#define portSYS_SSIR1_REG ( * ( ( volatile portUInt32Type * ) 0xFFFFFFB0UL ) )
#define portSYS_SSIR1_SSKEY ( 0x7500UL )
portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY;
__asm volatile
(
" DSB \n"
" ISB "
::: "memory");
which doesn't read back from portSYS_SSIR1_REG after writing to it, but does include a DSB. Assuming interrupts aren't masked, do we need to add a read-back from portSYS_SSIR1_REG to guarantee that an interrupt is raised immediately after the ISB is executed, or will there hypothetically be some delay in between the ISB and the interrupt being raised? Or is there something else entirely we need to do?
The two code samples above refer to specific modules, but does the sequence to guarantee a write has effected the active interrupts ever change depending on what module we're writing to? For example, enabling or disabling or clearing an interrupt in the VIM versus the DMA module versus the GIO module.