and just to be crystal clear, presumably all that needs to be done is something like the following:
#include <io.h># include <system.h># include "sys/alt_irq.h"
// ----------------------------------------------------------------------------
alt_irq_context IRQ_ALLOW_ESSENTIAL_START (alt_u32 id, alt_u32* pActive)
{
alt_irq_context Ctrl0;
alt_u32 irq_mask;
//mask out own IRQ and all others having lower priority level
irq_mask = ~(0x0FFFFFFFF << id);
// alternatively, mask out self and IRQs 32-29, 28-26
irq_mask = (~(1 << id)) & 0x01FFFFFFF;
*pActive = alt_irq_active;
alt_irq_active &= irq_mask;
NIOS2_WRITE_IENABLE (alt_irq_active);
/* alternatively......
alt_irq_disable (id); //Prevent re-entry
alt_irq_disable (<a lower priority interrupt that can wait>);
alt_irq_disable (<another lower priority interrupt that can wait>);
alt_irq_disable (<yet another lower priority interrupt that can wait>);
*/
NIOS2_READ_STATUS (Ctrl0);
Ctrl0 |= NIOS2_STATUS_PIE_MSK;
NIOS2_WRITE_STATUS (Ctrl0);
return (Ctrl0);
}
// ----------------------------------------------------------------------------
void IRQ_ALLOW_ESSENTIAL_FINISH (alt_irq_context Ctrl0, alt_u32 id, alt_u32 Active)
{
Ctrl0 &= ~NIOS2_STATUS_PIE_MSK;
NIOS2_WRITE_STATUS (Ctrl0);
/*
alt_irq_enable (<yet another lower priority interrupt that can wait>);
alt_irq_enable (<another lower priority interrupt that can wait>);
alt_irq_enable (<a lower priority interrupt that can wait>);
alt_irq_enable (id);
*/
alt_irq_active = Active;
NIOS2_WRITE_IENABLE (Active);
}
// ----------------------------------------------------------------------------
static void MyInterruptibleISR (void* context, alt_u32 id)
{
alt_irq_context Ctrl0;
alt_u32 Active;
<time-critical section, e.g. reading registers>
Ctrl0 = IRQ_ALLOW_ESSENTIAL_START (id, &Active);
<non-time-critical section, e.g. stuffing in buffers>
IRQ_ALLOW_ESSENTIAL_FINISH (Ctrl0, id, Active);
}
// ----------------------------------------------------------------------------