Not returning from ISR? Yes you can!

RaymanRayman Posts: 10,485
edited 2020-03-24 - 15:59:43 in Propeller 2
I have this cog waiting for a trigger on a pin, but need to get it out of that loop if the trigger pin changes...
I could just stop the cog and then restart it, but that seems wasteful...

Can I have an ISR that isn't actually meant to be returned from?
Can I just pop the stack and then jump to the start of the cog code or wherever?

Update: Ok, figured it out... Don't need to pop anything but you do need to either NIXINTx or RETIx to clear interrupt flag.

Comments

  • Documentation says:
    Interrupt branches are realized, internally, by inserting a 'CALLD IRETx,IJMPx WCZ' into the instruction pipeline while holding the program counter at its current value, so that the interrupt later returns to the proper address.
    

    I guess PC gets sent to IRETx and then it jumps to IJMPx.
    Maybe I don't need to pop anything...

  • I think I just need to set IJMPx to #0, do a SETINTx and it's done.
    Cog will essentially restart on interrupt...
  • It seems there's some internal mechanism that prevents the int from working more than once when I do it this way...
    RETx must clear some flag that allows the interrupt to work again.

    But, I did just figure out that NIXINTx clears this flag, so back in business...
  • You shouldn't need to nix the interrupt. What event is triggering your interrupt?
  • RaymanRayman Posts: 10,485
    edited 2020-03-23 - 18:40:05
    ATN

    oh wait... Maybe I need a POLLATN?
    I think I remember from something else that I needed a POLLATN for some reason...
    But, seems like nix has the same affect...
  • evanhevanh Posts: 9,042
    edited 2020-03-23 - 23:01:36
    From the main doc:
    The CALLD with D = <any register>, S = IRETx, and WCZ, signals the cog that the interrupt is complete. This causes the cog to clear its internal interrupt-busy flag for that interrupt, so that another interrupt can occur.

    Presumably NIXINTx clears that flag too.

  • I think what you're after is have the RETI do the branch back to address 0. So you still have an actual ISR. In that ISR you'll reset the IRET register to 0 value so that the RETI instruction will return to address 0.

  • Thanks evanh. I see now that there is an interrupt busy flag that needs to be cleared.
    Seems there are two ways to do this... IRETx or NIXINTx.
Sign In or Register to comment.