Is there some sample code on handling multiple interrupts and AINTC setup/operation for the ARM9 side of the L137. I am having a problem where I can get a timer tick interrupt to execute properly, ported FreeRTOS operating system and it runs threads fine. I can also disable the timer tick and run UART2 on interrupts with TX Empty and RX Data, with no problems. Thus proves service routines are functioning OK. Problem is if I attempt to enable both interrupts at the same time, timer tick runs fine until the UART interrupt request occurs (for example receive a character, or enable TX Empty interrupt). Although none of the AINTC registers show a pending UART2 interrupt (except raw interrupt status register SRSR), I can't clear the TIMER0 interrupt for the OS tick and once exit IRQ, re-enter immediately in an endless loop saying TIMER0 needs service, raw status set as well. Have tried nested and non-nested modes (CR set to 0 and to 0x18) but problem seems to be something not very happy in the AINTC of the ARM9. HIPIR2/GPIR continues to request TIMER0 service, even if disable the timer with JTAG. Set GER to 0 and can disable interrupts so at least that inhibits interrupts when race condition occurs.
If my understanding is correct the Global Index should be the same as the Host Pending IRQ Index with FIQ disabled at AINTC/CPSR level?
As a side note the linux distribution has alot of waitloops on UART register initialization, anyone know why? Wondering if undocumented errata issue?
In case someone can see something obvious, below is general interrupt handler that works fine until multiple interrupts. TIMER0 is priority 4 and UART2 is priority 7 also tried both at 4.
#define IRQ_ACTIVE_INDEX AINTC_GPIR
#define IRQ_ACTIVE_VECTOR AINTC_GPVR
//#define IRQ_ACTIVE_INDEX AINTC_HIPIR2
//#define IRQ_ACTIVE_VECTOR AINTC_HIPVR2
.global __irqHandler
__irqHandler:
portSAVE_CONTEXT
LDR R0, c_irqHandler
MOV lr, pc
BX R0
portRESTORE_CONTEXT
void irqHandler()
{
int irqIndex;
void (*function)();
// Check which interrupt occurred
irqIndex= IRQ_ACTIVE_INDEX;
// get vector from table
function = (*(unsigned int *)(IRQ_ACTIVE_VECTOR));
if (irqIndex) // sanity check
{
if (function != NULL)
{
if (*function == irqHandler) // sanity check to ensure table OK
{
count++; // debug counter to detect runaway IRQ
/*
* The ISR used for the scheduler tick depends on whether the cooperative or
* the preemptive scheduler is being used.
*/
#if configUSE_PREEMPTION == 0
vTaskIncrementTick();
#else
/* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */
vTaskIncrementTick();
vTaskSwitchContext();
#endif
TIMER0_INTCLSTAT = BIT0 | BIT1; // Enable interrupt and clear status
// only way to activate int again
// is write of BIT1, which is int status.
}
else
{
// normal interrupt to process, UART2 is handled here
(*function)();
}
}
else
{
count = 0; // NULL breakpoint location
}
}
else
{
count = -1; // error breakpoint location
}
AINTC_SICR = irqIndex; // clear interrupt
}