Problem enabling FPGA interrupts with FreeRTOS and Zynq 7000

wonger wrote on Thursday, June 25, 2015:

I’m running FreeRTOS on a Zynq 7000 (dual core ARM Cortex-A9, but only using 1 core for FreeRTOS). I enabled FPGA2 interrupt (IntID 63) with the following:

XScuGic_Connect( &xInterruptController, XPS_FPGA2_INT_ID, (Xil_ExceptionHandler) FPGA2_IntHandler, NULL);
XScuGic_SetPriorityTriggerType( &xInterruptController, XPS_FPGA2_INT_ID, configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT, 3 );
XScuGic_Enable(&xInterruptController, XPS_FPGA2_INT_ID);

The FreeRTOS tick timer interrupt handler is triggering, but not this FPGA2 interrupt handler. I can see the interrupt input line toggling on spi_status_0 register. This code on a bare-metal application triggers the FPGA2 interrupt handler, but not in FreeRTOS. Anyone know what I’m missing?

Thanks for your help.

rtel wrote on Thursday, June 25, 2015:

I can’t see anything obviously wrong. Did you use the code in vConfigureTickInterrupt() as a reference?

I’ve never tried using that particular interrupt - is there anything different about it compared to say the UART or Ethernet interrupts? [both of which I have used]

wonger wrote on Thursday, June 25, 2015:

I found out the problem. I put the FPGA2 interrupt enable code above in prvSetupHardware(). I adapted the demo code from the blinky demo, so I’ll put everything in context of that. When main_blinky() runs, it calls vTaskStartScheduler() which eventually gets to vConfigureTickInterrupt().

vConfigureTickInterrupt() calls XScuGic_LookupConfig() and _CfgInitialize() again (they were already called in prvSetupHardware()). This clears out the FPGA2 interrupt enable bit and renders it disabled.

To get it to work, I took out the calls to XScuGic_LookupConfig() and _CfgInitialize() and removed the static reference to xInterruptController in vConfigureTickInterrupt(). I used the global xInterruptController defined in main.c instead, the one initialized by prvSetupHardware().

Is there anything wrong with what I did to get it to work? Why in the demo code does vConfigureTickInterrupt() use a static reference to the interrupt controller rather than the global one define in main.c? Will anything come back to bite me in removing the static reference and using the global one?

wonger wrote on Thursday, June 25, 2015:

It also occurred to me that if I put the FPGA2 interrupt enable code in prvQueueSendTask() or prvQueueRecieveTask() (the tasks that drive the blinky demo), I would not have run into this problem. And perhaps that is the more proper place to put this code? Not in those tasks per se, but in a related task that would use FPGA2 interrupt.

richard_damon wrote on Friday, June 26, 2015:

Note that the vConfigureTickInterrupt() is demo code (and thus part of the application) and NOT ‘FreeRTOS Kernal code’ that shouldn’t normally be changed. I have changed that code to use a common instance so the ScuGic isn’t reinitialized at this point (and thus lose all the interrupt previously enabled).