cancel
Showing results for 
Search instead for 
Did you mean: 

Daisy chained interrupt errata fix

sjackson
Associate II
Posted on November 18, 2009 at 04:27

Daisy chained interrupt errata fix

11 REPLIES 11
nle
Associate II
Posted on May 17, 2011 at 09:56

stmicro support engineer has given me permission to post this information. now i understand more how it works in structure and sequence. we have implemented the AN2593 recommendation just the other day. hopefully this fixes our problems.

=========================================

Dear User,

Please find here below latest information concerning the request R09450103

Erwin,

Ok. Looks like I will have to provide a detailed explaination.

Not sure if you have read the ARM document about the VIC IP so I am attaching the document for your reference. Note that VIC controllers (VIC0 and VIC1) are IPs from ARM and the details we have provided on the our reference manual and AN2593 application note is based on this.

If you look closely on the VIC diagrams, the interrupt controller and the ARM9 core are two separate entities. You know that the ARM9 has only two interrupt lines, FIQ and IRQ. While the VIC0 and the daisy-chained VIC1 hands all the interrupt lines comming from peripherals.

VIC0 and VIC1 also handles the prioritization. The ARM9 only waits for an FIQ or IRQ signal and will just fetch the address of the interrupt subroutine provided by VIC0. The ARM9 only cares about FIQ and IRQ prioritization and not the prioritization defined on VIC0 and VIC1. Now with this in mind, it would be easy for you to understand my explaination why there is a need to read and write to the VAR in your interrrupt service routine (ISR).

When an interrupt occurs, say on VIC0 (e.g. ADC generating the interrupt), of course the VIC0 will handle the prioritization. And when it resolves the prioritization, it will put the address of the ISR into the VIC0_VAR. And then the VIC0 generates an IRQ signal, for example, to the ARM9 core. This you should know already. Now at this point the VIC0 will keep this interrupt request active. When the ARM9 core receives the IRQ signal, it will call\jump to the GLOBAL IRQ handler. You will find this handler in the 91x_vect.s file. In this handler, this where the VIC0_VAR is read to fetch the address of the ISR and then the program counter (PC) will jump to the ISR handler function (e.g. ADC_IRQHandler where ADC is on VIC0).

Now the reason for READING the VAR, aside from fetching the address and jumping to the ISR, is for the ARM9 core to tell the VIC0 that the core is now handling the interrupt and that the VIC0 should now take note and manage the prioritization, etc. Now at the end of ISR, the ARM9 core will also need to tell the VIC0 that the core has finished executing the ISR. The mechanism to do this is by WRITING a dummy data to the VIC0_VAR. This mechanism allows the VIC0 to be able write a new ISR address to the VAR if there are pending interrupts. The WRITING operation\event is basically a signal that the ARM9 core has finished executing the ISR and this triggers an update for a new ISR address if there are pending interrupts (otherwise it will put in the default interrupt handler address - DefaultVector_Handler).

Note that in the Global IRQ Handler, only the VIC0_VAR is accessed by the core. This is because the VIC0 is responsible of singalling the IRQ and managing and providing the address to the core.

Now if the interrupt source is from a peripheral assigned on the VIC1 (e.g.USAR0), the VIC1 will of course manage the priorities and then VIC1 will pass the address to VIC0 and after managing the priority, VIC0 will put the address on the VIC0_VAR. Then same thing will happen as before, but in your interrupt service routine\handler you will need to perform a READ on the VIC1_VAR as well to tell the VIC1 that that the ARM9 core is now executing the ISR. And when you exit for the ISR, you only need to WRITE a dummy data to the VIC1_VAR. No need for VIC0_VAR.

This is clearly explained in the AN2593. And you are also provided an sample source as companion of the AN2593. Please use this sample source code as reference in writing your interrupt service routine. Note that on this sample code, you are able to handle nested interrupts. The addition of the IENABLE and IDISABLE macros makes nested interrupts possible.

I understand your concern on the WRITING operation but this operation is simply to signal the VIC that the core is finished with the current request. It does not really overwrite the content. It only sort of ''unlocks'' the VAR to be updated with a new ISR address.

If you have an nested interrupt, all information of the current context will be PUSHed to the stack and later will be POPed from the stack so you do not loose the return address and the previous context. You will see these in the IRQ Handler in the 91x_vect.s file.

Note that you will need to clear the request flag from the peripheral side (e.g. UART0) to prevent the VIC from re-issuing the interrupt request all over again. But I guess you know this already.

If you are looking at the sample source code for the STR9 eval board included in the firware library, please take note that the implementation is for concurrent interrupts. You can still use these codes as reference but I strongly recommend to use the sample code in the AN2593 for proper management of the daisy-changed interrupt.

In summary:

READING the VAR:

- updates the priority logic in the VIC and will also masks any interrupt with the same or lower priority level. It basically tells the VIC that the core will now execute the interrupt.

WRITING to the VIC0_VAR or VIC1_VAR depending on the source of the interrupt:

- updates again the priority logic in the VIC and this will allow the same or next and lower priority interrupts to generate an IRQ to the core. It basically tells that the core has finished executing the corresponding interrupt handler.

If you look at the reference manual, Table 13 VIC Interrupt Channels, you will see which peripheral interrupt is connected to which VIC. Refer to this so that you will know whether you need to READ VIC1 and to know which VIC to WRITE.

=========================================

[ This message was edited by: nle on 13-11-2009 11:39 ]

[ This message was edited by: nle on 13-11-2009 11:43 ]

nle
Associate II
Posted on May 17, 2011 at 09:56

It is an interesting question. And I would like to find out also if my understanding is correct or not. Please correct me if it is wrong.

The FIQ has higher priority than IRQ so FIQ can interrupt IRQ if you do not touch the F-bit inside IRQHandler.

To prevent IRQ nesting, that is another IRQ interrupting an ongoing IRQ, you should leave the I-bit as it is inside IRQHandler and dont re-enable IRQ interrupts.

Dummy write to VIC0.VAR should be implemented in all VIC0 interrupt handler functions assigned to IRQ.

It is not necessary to read or write VIC0.VAR during an FIQ interrupt. If there is only one source, you can process the interrupt immediately. If there are more than one sources, FIQ status register must be checked to determine which one triggered the FIQ.

The current IENABLE/IDISABLE macros are intended for IRQ nesting to allow other IRQ to interrupt current IRQ. It is not needed by FIQ as it already has higher priority than IRQ.