=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Date: Fri, 15 Oct 1999 18:19:22 From: "Nikolai Golovchenko" To: "pic microcontroller discussion list" Subject: Re: Nested Interrupt questions -------------------------------------------------------------------------------- Yes, the nested interrupts are possible. The method I used on 16F84 processed two interrupts (RBIF and TMR0IF), but more interrupts could be okay. To do this, I use software stack macros (see attachment) that use FSR as a stack pointer. A typical interrupt handler looks like this: ORG 0x004 ; interrupt vector location PUSHW ;store W PUSHSTATUS ;store STATUS ;code goes here POPSTATUS ;restore W POPW ;restore STATUS retfie ; return from interrupt After storing W and STATUS goes usual interrupt flags polling . As soon as a set flag is detected, it should be cleared and GIE=1 to allow other interrupts to actually interrupt the process. Be careful not to allow too many interrupts to be processed, only the ones that have critical response time, because hardware stack may overflow. The best way is to keep GIE reset during the most critical interrupt so that it could finish without unwanted interrupts. Priority of different interrupts is programmed by flags polling sequence(in case they trigger at the same time). That's it. By the way, I find software stack macros very useful in practically every program. The best example is when you need one scratch pad register. Using stack it's simple: PUSH ;reserve one byte on stack ....use INDF as a scratch pad reg POP ;restore stack Good luck. ;******************************* ;Software stack organization ;******************************* ;FSR is a stack pointer ;Top of stack is in INDF ;Stack grows in upper addresses direction ;******************************************************************* ;MACRO: INSTR.NUMBER: STATUS INFLUENCE: W INFLUENCE: ; ;PUSHW 2 no no ;POPW 3 no yes ;POPW2 2 yes!!! yes ;PUSHSTATUS 3 no yes!!! ;POPSTATUS 3 yes yes!!! ;PUSH 1 no no ;POP 1 no no ;******************************************************************* ;Notes: 1) FSR should point at the stack top ; 2) PUSHSTATUS and POPSTATUS must be used in pair, ; because these macros mangle quadruples ;******************************************************************* PUSHW MACRO INCFSZ FSR, F ;never goes zero, but STATUS is safe MOVWF INDF ENDM POPW MACRO SWAPF INDF, F SWAPF INDF, W DECFSZ FSR, F ENDM POPW2 MACRO MOVF INDF, W DECFSZ FSR, F ;the popped W STATUS is safe ENDM PUSHSTATUS MACRO SWAPF STATUS, W INCFSZ FSR, F ;never goes zero, but STATUS is safe MOVWF INDF ENDM POPSTATUS MACRO SWAPF INDF, W MOVWF STATUS DECFSZ FSR, F ENDM PUSH MACRO INCFSZ FSR, F ENDM POP MACRO DECFSZ FSR, F ENDM -----Original Message----- From: Thomas Brandon To: PICLIST@MITVMA.MIT.EDU Date: Tuesday, October 12, 1999 3:59 AM Subject: Nested Interrupt questions >Has anyone written a program that dealt with interrupts occuring during an >interrupt. I know there are no nested interupts but from reading the docs, >the following 2 methods should allow (some) interupts during interrupts to >not be missed (delayed, but not missed): >1) Process interrupt as normal. Clear bit of specific interrupt dealt with. >Copy the PIR registers to memory and then clear them. In code after >interrupt, check saved register and deal with any other interupts. The >pseudocode would then be something like this: > >Interrupt Handler: > Find interrupt cause > Handle interrupt (1) > Clear appropriate bit > Copy PIR's to memory (2) > Return From interrupt (3) > >Any interrupts between (1) and (2) would set the appropriate PIR bit , but >as the GPIE is clear no interrupt will occur. Any interrupts occuring >between (2) and (3) will trigger after (3) due to the GPIE being set again >via RETFIE. The only problem is if this occurs what do you do with the >interupts saved at (2) but not yet dealt with. You could deal with this at >the beginning of the interrupt handler but this could considerably lengthen >the interupt processing time. > >This is really only suitable when all processing is interrupt triggered. The >background loop would simply continually check the appropriate memory for >missed interrupts. This is about all this loop could do assuming reasonable >interrupt response is needed. > >2) Simply ignore the fact that multiple interrupts can occur. Do priority >interrupt handling (i.e. deal with only one interrupt at a time) and only >clear the appropriate bit. Thus when RETFIE is called and GPIE is set any >pending interrupts will trigger. > >The 2nd method is slightly more flexible in that background processing can >continue however it means interrupts will be delayed by other interrupts. >After calling RETFIE there will be an approx. 3TCY delay to the next >interrupt trigger. Hence if 3 interrupts occur at once there will be 6TCY >and the processing time of the other 2 interrupts delay. Also, to ensure >adequate handling of critical interrupts, priority checking must be done >adding further processing time. > >Both of these methods could be improved by simultaneously handling multiple >interrupts where appropriate but again extra logic is required. > >Has anyone implemented an interrupt critical system on a PIC? How did you >get around the problem of overlapping interrupts? Are there any problems in >the above methods? > >Tom. > >