Question about POPing from stack

I have a main program that looks something like this:

Main btfsc PORTB,4 call pin_high btfss PORTB,4 call pin_low btfsc condtion1 call routine1 btfsc condtion2 call routine2 btfsc condtion3 call routine4 btfsc condtion5 call routine5 goto main

routine1 do whatever return

routine2 do whatever return

routine3 Etc.

Interupt service routine run some code set condition 1,2,3,4 or 5 flag depending on result retfie

Over all the program works fine BUT if for example the program was at the line in the main routine "btfsc condtion2" when the interupt occurs, when it POPs out of the interupt routine it will return to PC+1. Hence it will end up on "call routine2" and will execute "routine2" even if that condition was not set. ... call routine1 NOP btfsc condtion2 call routine2 ...

Inserting a NOP seems to solve the problem because now it will end up at "btfsc condtion2" when it POPs and will not run the routine unless it's supposed to.

This is a really quick and dirty solution and is floored because the code only has be increased or reduced in size by one instruction for the NOP to be in the wrong place.

Any better suggestions? help please :)

Andy

Reply to
maccyd10
Loading thread data ...

"something like " is not good enough, try postoing your actuall code.

Reply to
cbarn24050

What chip are you using?

Maybe you're misintepreting what's happening.. interrupts should not ever cause incorrect branches as you suggest, unless there's a very serious errata with the chip.

Best regards, Spehro Pefhany

--
"it\'s the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

The simplest fix would be to re-test the conditionX bit a second time when you enter the conditionX routine, and jump out if it's clear. I am assuming that the btfsc instruction did not change the bit, but if it did then use another type of branch instruction.

Reply to
Fred Bloggs

If those condition routines can be interrupted too then the BTFSC can do the same thing there so you would end up executing the return instruction erroneously. If you entered the routine erroneously then this is okay because in this case two wrongs do make a right, but if you entered the routine correctly then it means you will have to cycle through main a second time, the bit will still be set so you end up coming back to the routine again where BTFSC can be interrupted again , however improbably, and you erroneously jump back to main, ad infinitum.

Reply to
Fred Bloggs

Once your code has discovered "... condition 1,2,3,4 or 5 flag depending on result" then use a

"computed jump"

to goto routine1,2,3 etc e.g. see:

formatting link

Cheers Robin

Reply to
Robin

Maybe you decided to ignore the "swapf STATUS,w" at the end of the isr because you found a simpler way to do it :) I know I did :) and *that* is why status is corrupted in your code.

You must stick with the published isr in the documentation. Here is a copy of it with some comments added:

isr ;p 140 movwf doubleyou ;could be in either bank (p. 141) swapf STATUS,w ;preserve status in w movwf status ;status saved in common ram too ... swapf status,w ;recover and restore nibble order in w movwf STATUS ;status (and original page) restored swapf doubleyou,f ;prepare to... swapf doubleyou,w ;...recover W (without affecting status) ;bcf INTCON,intcon_rbif ;clear interrupt flags before enabling... ;bsf INTCON,intcon_rbie ;...interrupts to avoid self_calling (p19) retfie

Cheers Robin

Reply to
Robin

"maccyd10" wrote in news:1129419282.225832.303150 @g49g2000cwa.googlegroups.com:

disable interupts for critical routines, then turn them back on when finished....

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----

formatting link
The #1 Newsgroup Service in the World! 120,000+ Newsgroups

----= East and West-Coast Server Farms - Total Privacy via Encryption =----

Reply to
me

Here is my example (write your subroutines as macros called "subroutine1,2,3 etc")

If you hate the macro technique then extract the code and use it directly but it may not be as clear in the long run.

Cheers Robin

;************************************************************************ ; jumper: goto(here + offset_in_W) * * ;*********************************** * ; Computed goto (see AN556). * ; * ; Expects:W == offset * ; jumptable == concatenated to this macro * ; * ; Uses: temp * ;************************************************************************ jumper macro local jumper_10 local jumptable movwf temp movlw LOW jumper_10 addwf temp,w movlw HIGH jumper_10 btfsc STATUS,stat_C_bit addlw D'1' movwf PCLATH movf temp,w jumper_10 addwf PCL,f jumptable ; jump table starts here. endm

jumptable macro jumper goto subroutine1 ; == 0 goto subroutine2 ; == 1 goto subroutine3 ; == 2 goto Abort ; dummy == 3 goto Abort ; dummy == 4 goto Abort ; dummy == 5 goto Abort ; dummy == 6 goto Abort ; dummy == 7 goto Abort ; dummy == 8 goto Abort ; dummy == 9 goto Abort ; dummy == A goto Abort ; dummy == B goto Abort ; dummy == C goto Abort ; dummy == D goto Abort ; dummy == E goto Abort ; dummy == F

Abort subroutine1 subroutine2 subroutine3 return endm

Reply to
Robin

There were some truly horrible errata with some relatively recent units, especially when operating at full speed, in which the workaround involved NOPs. I don't recall the details, but I'd prefer to stay completely away from those parts until they at least have the core working as advertised.

But I'm guessing it's a context save/restore issue. With the PIC its really best to look up Microchip's advice on how to do context save/restore as it's a bit arcane (in the midrange architecture swapf (nibble swap) instructions are required to move one of the bytes , as someone else mentioned-- in order to avoid screwing up the STATUS flags (swapf doesn't affect flags), and there are a couple of different banking issues).

Best regards, Spehro Pefhany

--
"it\'s the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

Sounds like a typical microprocessor "feature" with the standarsd solution of adding a NOP in the poper place....

Reply to
Robert Baer

Hi guys, problem solved.

At the end of isr I bsf possible_bad_entry and clear it again at the end of main. I test for it in each sub and return of not clear. Now it must run though main at least once befor the any subs can be run.

for those of you who asked the pic is a p16f628 and my isr is the usual, like the one below.

Cheers.

Andy.

#define myflags,0 possible_bad_entry

myflags equ 0x??

Main btfsc PORTB,4 call pin_high btfss PORTB,4 call pin_low btfsc condtion1 call routine1 btfsc condtion2 call routine2 btfsc condtion3 call routine4 btfsc condtion5 call routine5 bcf possible_bad_entry goto main

routine1 btfsc possible_bad_entry return do whatever return

routine2 btfsc possible_bad_entry return do whatever return

routine3 btfsc possible_bad_entry return Etc.

service_timer2 run some code bsf conditionx return

isr movwf wSAVE swapf STATUS,w bank0 movwf statusSAVE swapf PCLATH,w movwf pclathSAVE clrf PCLATH clrf STATUS call service_timer2 exit_isr bank0 swapf pclathSAVE,w movwf PCLATH swapf statusSAVE,w movwf STATUS swapf wSAVE,f swapf wSAVE,w bcf PIR1,TMR2IF bsf possible_bad_entry retfie

Reply to
maccyd10

Hi guys, problem solved.

At the end of isr I bsf possible_bad_entry and clear it again at the end of main. I test for it in each sub and return of not clear. Now it must run though main at least once befor the any subs can be run.

for those of you who asked the pic is a p16f628 and my isr is the usual, like the one below.

Cheers.

Andy.

#define myflags,0 possible_bad_entry

myflags equ 0x??

Main btfsc PORTB,4 call pin_high btfss PORTB,4 call pin_low btfsc condtion1 call routine1 btfsc condtion2 call routine2 btfsc condtion3 call routine4 btfsc condtion5 call routine5 bcf possible_bad_entry goto main

routine1 btfsc possible_bad_entry return do whatever return

routine2 btfsc possible_bad_entry return do whatever return

routine3 btfsc possible_bad_entry return Etc.

service_timer2 run some code bsf conditionx return

isr movwf wSAVE swapf STATUS,w bank0 movwf statusSAVE swapf PCLATH,w movwf pclathSAVE clrf PCLATH clrf STATUS call service_timer2 exit_isr bank0 swapf pclathSAVE,w movwf PCLATH swapf statusSAVE,w movwf STATUS swapf wSAVE,f swapf wSAVE,w bcf PIR1,TMR2IF bsf possible_bad_entry retfie

Reply to
maccyd10

It is easy enough to verify, if he lands in RoutineX when the X-condition bit is clear then he has an interrupt problem.

Reply to
Fred Bloggs

I haven't looked at PICs nearly enough, but if it doesn't push the condition codes on interrupt, and pop them back at return from interrupt, then it's a seriously flawed design. It also should be impossible to interrupt in the middle of an instruction cycle.

Thanks, Rich

Reply to
Rich Grise

There is a Microchip App note somewhere that deals with interrupts. There is some quirky behaviour from memory, but I think that was only to do with the instructions affecting carry bits etc.

Reply to
The Real Andy

PowerPC doesn't push CCs onto the stack on an interrupt either. In fact it doesn't push anything onto the stack. There isn't one (in hardware, anyway). Don't limit your brain to x86. Not all processors operate teh same way.

--
   Keith
Reply to
keith

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.