Hello,
i'm programming an "reset"/"abort" ISR in my program(essentially a kind of "emergency stop" button, so i can't simply set a value in a variable and return to the main loop.
Main loop has lots of delays and if/for loops that need to be instantly aborted should the button be pressed.
Now, i'm having a couple issues with this:
- i need to implement a small delay inside the ISR, since Delay() doesn't works i thought about using a simple for with inline NOPs, but i'd like to at least be able to somewhat calculate how much the delay is, the delay line i arbitrarely built is: for(int z = 0; z < 500000; z++) asm("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); so that's AT LEAST 50000 iterations of 3 NOPs, but i have no idea how much overhead the for/increment generates, if i take the NOPs alone, that's 500K x 62.5nS x 4 =125mS
i need at least 3 to 4s, so i'd need to do a z <16000000 right?
now the main problem:
2) the "reset" button(not the arduino reset mind you) needs to stop all running stuff, as you can see in the code i cycle a relay(that's part of a need for the rest of the circuit) and set the "contando" varibale to false(a very long counting timer event in main loop), my concern is that main loop has a for() loop with large delays inside that need to get aborted, so if i run this right now, the ISR executes, does it's thing and then returns the stack to the previous position!, which could be inside a Delay() or the for() loop and then everything would execute the same!.
How can i force the ISR to return to a specific PC address(POPing the PC from a previus PUSH i should do in the beginning of the main loop, something like that comes to mind) instead of just returning to last PC+1?.
I don't want to have reset the AVR itself for this(using a pin jumped to the reset input and issuing a digitalwrite there....) as it's anything but elegant, or am i going to have to write a new special ISR in an assembler macro just for this?
code follows:
void reset_event(){
digitalWrite (rele, HIGH); //activar rele para resetear el UC3906, delay no funciona en el ISR
for(int z = 0; z < 500000; z++) __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
digitalWrite (rele, LOW); //desactivar rele para operación normal
contando = false; //abortar cuenta
}