Newbie RETI question: can an ISR exit with a JMP to a particular line?
CarlC
Posts: 29
Is it possible to exit an ISR with a JMP to a label in the main program instead of returning to the point of interruption?
I'm working on a device which needs to move to the beginning of either of two loops in my main on the detection of either of two input pin conditions.
rb.0 - mode switch
rb.1 - input signal pin
rb.0 will be connected to a mode switch which will jump to either of two main loops in my main body. The beginning of one loop will disable the interrupt for rb.1 so the mode loop can execute despite changes to rb.1. The beginning of the loop will also reconfigure the rb.0 interrupt conditions to detect the switch being moved back and run the ISR again.
rb.1 run the ISR to start a second major loop which polls the status of several other data pins.
Basically I'm hoping to use the ISR as a rapidly callable routine to switch between program modes without having to poll pins throughout my program operation to change operating modes. Will I run into problems if the register that RETI points to isn't cleared if RETI isn't used to return to the main?
I'm working on a device which needs to move to the beginning of either of two loops in my main on the detection of either of two input pin conditions.
rb.0 - mode switch
rb.1 - input signal pin
rb.0 will be connected to a mode switch which will jump to either of two main loops in my main body. The beginning of one loop will disable the interrupt for rb.1 so the mode loop can execute despite changes to rb.1. The beginning of the loop will also reconfigure the rb.0 interrupt conditions to detect the switch being moved back and run the ISR again.
rb.1 run the ISR to start a second major loop which polls the status of several other data pins.
Basically I'm hoping to use the ISR as a rapidly callable routine to switch between program modes without having to poll pins throughout my program operation to change operating modes. Will I run into problems if the register that RETI points to isn't cleared if RETI isn't used to return to the main?
Comments
If you really want to make use of an interrupt to detect level changes at the rb.0 and rb.1 inputs, you could have both inputs activate the ISR. Within the ISR, you check which input caused the interrupt, and set global flags, i.e. two bits on a register to indicate which input caused the interrupt. In the main loop, you can then check these flags, and branch into different code in the main loop. Don't forget to reset the flags in the main loop after testing them in order to "arm" them for the next interrupt.
Instead of polling the two flags, you might consider directly polling the inputs. It depends on how short puses occuring at the inputs are, and how often you can poll the inputs in order not to miss any. Instead of polling the inputs, you may also read the WKPND_B register (without having interrupts enabled) in order to catch very short pulses.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
Post Edited (Paul Baker) : 1/5/2006 2:23:21 PM GMT
I like your book by the way. My background is actually mechanical engineering so I need all the help I can get. The Basic Stamps were an easy entry, but the SX certainly has a lot more issues to think about.
Paul: thanks for the suggestion. I like it. It's my brand of jury rigging something with flagrant disregard for the right way to do things.
"Is it possible to exit an ISR with a JMP to a label in the main program instead of returning to the point of interruption?"
This is exactly what Peter's method of adjusting the shadow registers within the ISR does.· Look no further, this is the best way to do what you want.
Nate
Unfortunately I haven't developed the brainpower to really understand his code. However I think I've come to some sort of understanding.
Am I to understand that I should be ok using JMP to exit the ISR to go to whatever part in the main as long as I don't care about the initial state of PC, FSR, STATUS, or W just before interruption?
It appears to me that Peter has gone through some trouble to keep the chain of threads resumable after servicing sequential interrupts. My program needs are actually pretty simpleminded. I'm not concerned with the resumption of tasks after interruption. I'm actually using the ISR as a quick and dirty way of monitoring a parallel data line through polling while allowing for two interrupt conditions to abandon the data line monitoring and immediately jump to code loops. I tried to do the job by planting code to poll for my interrupt condition, but it got pretty messy having to stick the poll commands into each wait loop in my main.
I'll give it a go and see what kind of mess I make as usual.
If you use JMP and never return to the RETI command you have effectively cancelled the
interrupt capacity of the SX. I.E. you end up with the SX doing one interrupt and after it enters
the ISR and you never execute an RTI (or RETIW) you end up having the SX act as a normal
CPU without any more interrupts. Since upon entry into the ISR the SX disables any further Interrupts.
The SX enables further interrupts as part of executing the RETI/W instruction.
If all you want is the SX to respond to one interrupt once only and then do something and you do not
need to ever do the same thing again (that is in response to whatever caused the Interrupt), then use
JMP by all means.
However, that is not why (or how) Interrupts are used. You should always (strictly speaking) return
eventually from the ISR with a RETI/W.
I think that you are not quite grasping the use of interrupts. A very good explanation of what to do
is Gunther's Book.
Why not have the ISR set some flags and then issue an RTI/W and then your program can act upon
these flags and then reset them so that the next invocation of the ISR will be able to set them again
to indicate the occurence of the event that you are monitering.
Regards
Samuel
Post Edited (SamMishal) : 1/6/2006 10:38:21 AM GMT
would be a bit easier if we knew a bit more about your timing requirements, i.e. what is the shortest pulse length, and the shortest pulse period to be handled correctly?
As Samuel suggested, having the ISR set flags according to vertain events is a good idea to pass over such information from the ISR to the main program. This way, the ISR gets fired up asynchronously on certain input events, and (similar to a D-FlipFlop) saves the events in flags. The main loop needs to check the flags periodically, and often enough to not miss two subsequent pulses, and finally reset the flag(s), like resetting the D-FlipFlop.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
More serious forums deserve less goofy names anyways.
Sam, I realize that I do have to reset the appropriate reg's on reentry to main. I planned to do that at the beginning of the destination loops that the ISR would JMP to.
Geunther: I am attempting to scan a GPIB to look for a certain chain of bytes put across 8 I/O lines. I have loops set up to do comparisons when a DAV line is asserted true. In essence my intention is to wait in a minor loop for an ATN line to be asserted false (this indicates a device specific command or data). Once the ATN line is false (high) the first loop looks for the first byte in my sequence when the DAV (data ready) line is true (low). When the first byte is found, the loop exits to look for the second byte in my sequence. If the second byte does not occur on the next DAV assertion, (i.e. wrong byte value) the second minor loop JMPs to the first loop looking for the first byte again.
I wish to use interrupts to detect if the ATN line becomes true during the search loops because if this occurs, the message being sent across the bus is a bus management command which I am not interested in. It also indicates that the chain of bytes I'm looking for is not coming in this bus sequence so the search should reset to looking for the first byte.
I am also looking to use interrupts to detect a mode switch being flipped which should halt the byte sequence search and set the device to an adjustment mode where the user can change device settings.
I'm using polling for the byte searches beause I need relatively fast response. The refresh rate on the data lines can pass 1Mbyte which is pretty quick. I've stretched out the time that a byte is available with an 8bit latch which holds the value until the DAV line is recycled so I at least don't have to catch a byte in the short time that the bus holds it valid (the byte may change while DAV is false).
I'm hoping to use interrupts because the flag checking code might add extra cycles in the byte searching loops. It's already kind of bad that I will be losing 3 cycles per loop refilling the pipe while spinning in a byte comparison loop. At 50Mhz that's not too bad because I should get around 10 looks at the data pins per loop. If I put in flag comparisons I'll be down to 6 or 7.
Usually I work with the Basic Stamps. Most of my electromechanical things can't really react all that fast in the physical world so I've gotten away with higher level programming. I did think about using a SX chip in a simpler capacity though. Initially I was planning to use it for just the byte comparison job to tell the Basic module to do it's thing. In the end, I think I'd like to integrate everything into the SX processor because the code on the Basic module is actually pretty simple too so I might as well save the extra cost of the Basic module.
Even though you technically have two flags to check (4 cycles to check both), you can use a master bit that is the OR value of the two flags to·keep the main loop flag checking at 2 cycles, then check each flag when you perform the main loop exception.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
Post Edited (Paul Baker) : 1/6/2006 9:55:22 PM GMT
I guess I'm making a bit much ado about nothing. 5x oversample is not a bad margin of oversample with the flag checking in each subloop. As it stands, my data logger which tells me what sequences to look for is sampling at 5x oversample anyways. If I'm willing to accept that my measurement poll is oversampling at 5x, I should accept that 5x oversample is good enough for my device. I have speed paranoia because of inexperience. I got a bit of a shock when I first got a look at the GPIB signal with my crappy dusty steam powered 2MHz o'scope. It's been fun figuring out what tools I need to get into this area then figuring out how to use the things.
Thanks for the idea about checking for a single interrupt flag to catch the interrupt condition in the main subloops to save cycles. Checking the interrupt cause flag after exiting the subloop scan makes good timing sense. I'll set the ISR to set an "Interrupt Occured" flag and an "Interrupt Cause" flag so the subloops only look for the first flag then the second after exiting the scan routine then resetting them for subsequent use.