Shop OBEX P1 Docs P2 Docs Learn Events
Newbie RETI question: can an ISR exit with a JMP to a particular line? — Parallax Forums

Newbie RETI question: can an ISR exit with a JMP to a particular line?

CarlCCarlC Posts: 29
edited 2006-01-06 22:38 in General Discussion
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?

Comments

  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-01-05 10:18
    In your last sentence, you exactly describe what happens when you leave the ISR, using a JMP instead of a RETI instruction: The PC, FSR, STATUS, and W (and the M in SX48/52 devices) will not be restored.

    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
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-01-05 14:13
    Check out Peter's (pjv) submission to the SX contest, he uses undocumented SX assembly instructions within the ISR to mess with the stored context (FSR, Status etc) then RETIs but because the context has been changed, the ISR returns to a position he has specified. He uses this method to implement multitask switching, but you could use the same technique to do what you want, its just a little more involved than using a JMP.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·1+1=10

    Post Edited (Paul Baker) : 1/5/2006 2:23:21 PM GMT
  • CarlCCarlC Posts: 29
    edited 2006-01-06 02:15
    Thanks for your help Guenther. How would the flag setting work? Wouldn't I have to reach a comparison point in my loop after the RETI is exercised? My concern is that my major loops have several "do nothing" loops which poll for a particular pin input. I would have to check the flags in every sub loop then because I wouldn't know when the ISR would be called. I managed to lengthen the pulse time to make detection easier with a latch which is can be cleared with the ISR.

    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.
  • NateNate Posts: 154
    edited 2006-01-06 02:28
    Mad,

    "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
  • CarlCCarlC Posts: 29
    edited 2006-01-06 06:37
    I'm guessing Nate and Paul are referring to Peter Van der Zee's RTOS.

    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.
  • SamMishalSamMishal Posts: 468
    edited 2006-01-06 10:22
    MadMax (I guess you are Auzie ???)

    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
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-01-06 16:17
    MadMax,

    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
  • CarlCCarlC Posts: 29
    edited 2006-01-06 21:12
    Changed my login name. I think MadMax was getting too much attention. I'm a member of several forums, I try to stick to the same usernames to keep my end of things simple.

    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.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-01-06 21:52
    For this application you should use Guenther's method of flag setting and simply check for the flag each iteration of the main program loop. Doing this adheres to the time tested method of embedded programming. From what I understand, whenever you enter the ISR, you are in effect invalidating the current GPIB stream, so timing isn't critical when the ISR is entered. As far as the flag checking in the main loop a SNB instruction only consumes 2 clock cycles (skip taken branch) and a 5x data oversampling is sufficient for all but the noisiest environments (in which case oversampling only produces marginal benefits).

    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
  • CarlCCarlC Posts: 29
    edited 2006-01-06 22:38
    With the flag checking, I have to put the flag check into each byte polling subloop. With flag checking at only one point in the main loop, the ATN interrupt or mode switch interrupt wouldn't be acted on until a byte polling subloop aborts the sequence check.

    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.
Sign In or Register to comment.