We have found a problem that could cause the loss of edge triggered
interrupts.
The following section of code is from the
\hal\powerpc\mpc8xx\current\include\var_initr.h file, in function
cyg_hal_interrupt_acknowledge:
case CYGNUM_HAL_INTERRUPT_SIU_IRQ0 ... CYGNUM_HAL_INTERRUPT_SIU_LVL7:
{
// SIU interrupt vectors
cyg_uint32 sipend;
// When IRQx is configured as an edge interrupt it needs to be
// cleared. Write to INTx and IRQ/level bits are ignore so
// it's safe to do always.
HAL_READ_UINT32 (CYGARC_REG_IMM_SIPEND, sipend);
sipend |= (((cyg_uint32) CYGARC_REG_IMM_SIPEND_IRQ0)
>> (vector - CYGNUM_HAL_INTERRUPT_SIU_IRQ0));
HAL_WRITE_UINT32 (CYGARC_REG_IMM_SIPEND, sipend);
break;
}
In the MPC850 user manual, it states that:
"If an IRQ pin is defined as an edge interrupt, the corresponding
bit being set indicates that a falling edge was detected on the line and are
reset by writing ones to them."
This means that if an edge triggered interrupt comes in just after another
interrupt (while the first interrupt is executing) and the
cyg_hal_interrupt_acknowledge function is called, the second interrupt will
be lost and will nether be serviced.
The HAL_READ_UINT32 will read the SIPEND register which will contain two
bits that are set (one for each interrupt) this will then be written back to
the SIPEND register and will clear both interrupts.
A better solution could be to use:
sipend = (((cyg_uint32) CYGARC_REG_IMM_SIPEND_IRQ0)
>> (vector - CYGNUM_HAL_INTERRUPT_SIU_IRQ0));
HAL_WRITE_UINT32 (CYGARC_REG_IMM_SIPEND, sipend);
Is this correct are am I just using the cyg_hal_interrupt_acknowledge
incorrectly?