The cyclone v soc GIC interrupt priority issues
Hi,
I'm doing a baremetal multi task issue in cyclone V soc, I've learned that the cycloneVsoc used the PL390 GIC.
I now have 3 FPGA IRQs:
no.74 a timer counter interrupt every 50us (base tick).
no.75 a counter interrupt every 1ms based on the base tick.(fast task)
no.76 a counter interrupt every 5ms based on the base tick.(slow task)
What I want to achieve is that
1.base tick can not be interrupted and can interrupt other two IRQs.
2.The fast task can be interrupted by the base tick but cant be interrupted by the slow one.
3.The slow task can be interrupted by the others.
I've studied the GIC and found out it only choose the highest IRQ and send it to the CPU,
so I want to know whether it allow the high priority FPGA IRQ interrupt the low one.
Also, while makig the IRQ through the Avalon mm bridge, I was informed that irq signal must be set until the GIC told you that you are informed.
However, I want to use the edge trigger instead of level one.
Do you have any ideas to deal with that?
Reguards
Alex
Hi,
Please check this below API function, you can also directly set the LEVEL or EDGE triggered.
ALT_STATUS_CODE alt_int_dist_trigger_set(ALT_INT_INTERRUPT_t int_id,
ALT_INT_TRIGGER_t trigger_type)
{
// See GIC 1.0, section 4.3.12.
if ((uint32_t)int_id >= ALT_INT_PROVISION_INT_COUNT)
{
return ALT_E_BAD_ARG;
}
else if ((alt_int_flag[int_id] & INT_FLAG_IMPLEMENTED) == 0)
{
return ALT_E_BAD_ARG;
}
else if (int_id < 16)
{
if ( (trigger_type == ALT_INT_TRIGGER_AUTODETECT)
|| (trigger_type == ALT_INT_TRIGGER_SOFTWARE))
{
return ALT_E_SUCCESS;
}
else
{
return ALT_E_BAD_ARG;
}
}
else
{
uint32_t regoffset = int_id >> 4;
uint32_t regbitshift = ((int_id & 0x0F) * 2) + 1;
if (trigger_type == ALT_INT_TRIGGER_AUTODETECT)
{
if (int_id <= 32) { trigger_type = ALT_INT_TRIGGER_EDGE; } // PPI
else if (int_id <= 40) { trigger_type = ALT_INT_TRIGGER_EDGE; } // CPU0_PARITYFAIL
else if (int_id <= 47) { trigger_type = ALT_INT_TRIGGER_LEVEL; } // CPU0_DEFLAGS
else if (int_id <= 56) { trigger_type = ALT_INT_TRIGGER_EDGE; } // CPU1_PARITYFAIL
else if (int_id <= 63) { trigger_type = ALT_INT_TRIGGER_LEVEL; } // CPU1_DEFLAGS
else if (int_id <= 66) { trigger_type = ALT_INT_TRIGGER_EDGE; } // SCU
else if (int_id <= 69) { trigger_type = ALT_INT_TRIGGER_EDGE; } // L2_ECC
else if (int_id <= 70) { trigger_type = ALT_INT_TRIGGER_LEVEL; } // L2 (other)
else if (int_id <= 71) { trigger_type = ALT_INT_TRIGGER_LEVEL; } // DDR
else if (int_id <= 135) { /* do nothing */ } // FPGA, !!!
else { trigger_type = ALT_INT_TRIGGER_LEVEL; } // everything else
}
switch (trigger_type)
{
case ALT_INT_TRIGGER_LEVEL:
alt_clrbits_word(alt_int_base_dist + 0xC00 + regoffset * sizeof(uint32_t), 1 << regbitshift); // icdicfrn
break;
case ALT_INT_TRIGGER_EDGE:
alt_setbits_word(alt_int_base_dist + 0xC00 + regoffset * sizeof(uint32_t), 1 << regbitshift); // icdicfrn
break;
default:
return ALT_E_BAD_ARG;
}
return ALT_E_SUCCESS;
}
}
"Did you suggest I test the time form the isr signal send to GIC to the interrupt callback function called". Yes in C code only can write piece of code for timer before ISR start and end.
Regards
Tiwari