=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    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.
>
>