If I use the interrupt mode rising, falling, or changing, is there any chance of the interrupt being lost?
For example, if interrupts happen to be turned off right when the change happens, will the interrupt be queued, or will it be lost?
Also, is there a good way of blocking and re-awakening the loop() function, while still allowing interrupt handlers to execute?
Specifically, I'd like to "kick" the loop function in response to the rising edge of an input square wave (from a timer chip) tied to pin 2, and also on the user pressing any of my 4 input buttons (I'll have to rig some logic for this to generate a change on pin 3).
Here's the pseudo-code I want:
void int_pin_2()
{
interrupted = true;
source2 = true;
kick_main_loop();
}
void int_pin_3()
{
interrupted = true;
source3 = true;
kick_main_loop();
}
void loop()
{
int sources = 0;
if (!interrupted) {
wait_for_kick();
uint8_t sreg = SREG;
cli();
if (source2) sources |= 1;
if (source3) sources |= 2;
source2 = source3 = interrupted = false;
SREG = sreg;
}
do_stuff(sources);
}
This is pseudo-code, but I hope the intention is clear. If this were running on battery, a low-power state in wait_for_kick() would save battery, although "power off" is not needed -- this will actually run on wall wart, and I'm only trying to write code the way I feel it "should" be written.
Speaking of which: is this structure even a useful desired on the AVR? Is it worth it trying to "do nothing" when I know nothing is happening? Or should I just run loop() full bore and it won't harm or wear out anything? (Assuming I don't actually do anything other than return if there is no input).
I guess a third option is to put in delay(10) in the main loop, rather than wait_for_kick(), but that would increase my worst-case interrupt latency a smidgen -- again, probably doesn't matter for this application, but I don't want to go with "dirty" habits.