Can this be done? I know that calling cli() inside an ISR won't do it, because upon exiting the ISR will renable interrupts. I'm interested in a way for an interrupt to turn off interrupts as it exits (or, so to speak, not turn them back on), and have them remain off in the main code until a certain amount of time (a relatively short time, so micros measurement can be used, which isn't interrupt based to my understanding) has elapsed.
I know that a ISR_NOBLOCK flag can be used in the ISR's "function" definition to let interrupts stay on throughout it, but is there a way to have an ISR enter and run normally, except not have it undo any cli() commands issued within it when it exits? I can use a micros timing copied to a variable during the ISR and some logic in the main loop of code to handle the renabling of interrupts at an appropriately later time.
Thanks
Really you don't need this on a most arduino boards, because all other interrupts will be postponed automatically while the running the ISR. It is a normal behaviour of the system.
State exactly what this application is. There is surely a better way of achieving what you want. Generally prolonging the suspension of interrupts after an interrupt has been serviced sounds odd. Maybe ignoring specific interrupts if some condition is not met would be a solution.
My comment would be that it is absolutely possible to do what the OP asks, but I would never describe how, because it should NEVER necessary to do so. In 30+ years of doing embedded development, I have never once needed to do anything remotely like that. The fact the the OP thinks he needs to do this tells me his whole approach to his problem is wrong, and needs to be re-thought.
I had thought it could be a button push debouncing type problem where you could imagine a solution involving a prolonging of the interrupt suppression to prevent any following bounce. Of course the solution there is simply to ignore those interrupts for the next X ms.
Or you could disable that interrupt* within the ISR, then re-enable it later. That would prevent the bouncing from generating interrupts at all. I have a rotary encoder routine that switches the interrupt to the other line to prevent all those bounce interrupts.
Thanks, I can see how turning off the specific interrupt makes more sense than disabling entirely. That way I can have the interrupt trgger on the edge of an incoming communication signal (I've been setting up a protocol for a network of AVRs working together), and then not trigger again by any other events until a set amount of time has elapsed (ensuring if any one of them on the network were to go wrong and start spamming the bus with repeat messages others would be able to ignore some of the repeats and be able to keep doing individual tasks without being constantly interrupted).
You're over-thinking this. Just use a (volatile) flag within the ISR to tell it whether to do its thing or return immediately. Set / Reset that flag in both the ISR and the main code as necessary.
That's up to the programmer to decide, by default, they're not preemptive. The N in NVIC refers to nested interrupts, which involves the current ISR being preempted by a higher priority one. This is achieved by switching modes and enabling interrupts when entering an ISR.
ISR (PCINT0_vect ){
//various things
if(certain condition during interrupt){
PCICR &= 0b11111110;
}
//various things
TimeOfLastInterrupt=micros();
}
//then in the main loop
if(PCICR == 0){
//Serial.println("Int dis");//Interrupt disabled
//for debugging
}else{
//for debugging
}
if( ( (micros() - TimeOfLastInterrupt) > Period ) && (PCICR ==0)){ //Period us since last interupt and interrupt is disabled
PCIFR |= bit (PCIF0); // clear any outstanding interrupts
PCICR |= bit (PCIE0); // re-enable pin change interrupts for D8 to D13
//Serial.println("Interrupt re-enabled");
}
Oddly enough (PCICR & 0b00000001) ==0 wouldn't work in the main loop's if expressions, but as I'm not using the other two pin banks for change interrupts PCICR ==0 is good enough for my needs.