( software stacks on the PIC )
Nikolai Golovchenko says:
Yes, the nested interrupts are possible. The method I used processed two interrupts, 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 $004 ; interrupt vector location PUSHW ;store W PUSHSTATUS ;store STATUS ;code goes here POPSTATUS ;restore W POPW ;restore STATUS reti ; return from interruptAfter storing W and STATUS goes usual interrupt flags polling .
As soon as a set flag is detected, it should be cleared 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 not clear the interrupt flag 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 stackGood 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 incsz FSR ;never goes zero, but STATUS is safe mov INDF, W ENDM POPW MACRO swap INDF mov W, <>INDF decsz FSR ENDM POPW2 MACRO mov W, INDF decsz FSR ;the popped W STATUS is safe ENDM PUSHSTATUS MACRO mov W, <>STATUS incsz FSR ;never goes zero, but STATUS is safe mov INDF, W ENDM POPSTATUS MACRO mov W, <>INDF mov STATUS, W decsz FSR ENDM PUSH MACRO incsz FSR ENDM POP MACRO decsz FSR ENDM
Robin Abbott of Forest Electronic Developments says:
This might be of use to someone. Recently I had a project where a subroutine took a value in W and saved to a software stack:mov Temp, W mov W, sp ; Stack pointer mov FSR, W ; Point to it mov W, Temp mov Ind, WTrouble is it uses a temporary variable which I didn't have (it is in an interrupt). This alternative which makes use of XOR uses no temporary variable at the expense of 1 extra word:
mov FSR, W mov W, sp xor FSR, W xor W, FSR xor FSR, W mov Ind, WYou can also use this to swap two variables (say x and y) without a temporary variable leaving X (or Y if order is reversed) in W.
mov W, x ; Get X xor y, W ; Y is now X^Y xor W, y ; W is now (X^y)^X==Y (say OldY) mov x, W ; Now X is OldY xor y, W ; finally Y is (OldX^Y)^Y==OldXI think this may be an old technique - I have vague memories of something similar from the pre-history of programming, but only found a use for it now
Keep in mind, that on the SX 18..28, fsr.4 must be set after each decrement of fsr to prevent it from overwritting the global registers.
Paul Baker shares this code:
;----------------------------------------------- ; Constant Declarations ;----------------------------------------------- ;def _NOSMASH ;Unncomment to prevent stack over/underflows ;you must provide routines DUnderflow and DOverflow to handle exception ;and rptr which is maximum memory location ;def _SX52_ ;no wrapping code and move vars up to make room for ports D and E dstack equ $10 ;initial head of data stack (this is ajusted upwards when direct store variables are declared) ;----------------------------------------------- ; Variable Declarations ;----------------------------------------------- ifdef _SX52_ org $0A else org $08 endif wlo ds 1 ;low byte of working word whi ds 1 ;high byte of working word dptr ds 1 ;pointer to stack ;----------------------------------------------- ; ; Stack Functions ; ;----------------------------------------------- InitStack clr wlo ;clear working registers clr whi mov dptr, #dstack ;init pointer to data stack ret ;----------------------------------------------- ; Pushes contents of wlo onto data stack ; wlo -> stack+ ; Affects: w, dptr, fsr ;----------------------------------------------- DPush mov fsr,dptr ;load fsr with stack pointer mov ind,wlo ;store byte on top of stack inc dptr ;adjust stack pointer ifndef _SX52_ setb dptr.4 ;SX28 bank wrapping adjustment endif ifdef _NOSMASH cje dptr, rptr, DOverflow ;stack over endif retp ;----------------------------------------------- ; Pops top of data stack into wlo ; -stack -> wlo ; Affects: w, wlo, dptr, fsr ;----------------------------------------------- DPop dec dptr ;adjust stack pointer ifndef _SX52_ jb dptr.4, :noroll ;SX28 bank wrapping adjustment sub dptr, #16 :noroll endif ifdef _NOSMASH cjb dptr, dstack, DUnderflow ;stack under endif mov fsr, dptr ;load fsr with stack pointer mov wlo, ind ;fetch byte from top of stack retp ;----------------------------------------------- ; Fetchs wth element of data stack into w, ; only guaranteed to work with w<16 for SX28 ; stack(w)->w ; Affects: w, fsr ;----------------------------------------------- DPeek mov w,dptr-w ;adjust stack pointer by -w ifdef _NOSMASH cjb dptr, dstack, DUnderflow ;stack under endif mov fsr, w ;load stack pointer into fsr ifndef _SX52_ jb dptr.4, :noroll ;SX28 bank wrapping adjustment sub dptr, #16 :noroll endif mov w,ind ;fetch byte at stack pointer retp ;----------------------------------------------- ; Pushes wlo then whi onto data stack ; wlo,whi -> stack++ ; Affects: w, wlo, fsr, dptr ;----------------------------------------------- DPush2 call DPush mov wlo, whi call DPush retp ;----------------------------------------------- ; Pops top of data stack into whi then wlo ; --stack -> wlo,whi <-top of stack ; Affects: w, wlo, whi, fsr, dptr ;----------------------------------------------- DPop2 call DPop mov whi, wlo call DPop retp