Hi.
Regarding the EIFR - External Interrupt Flag Register ATMEGA 2560 datasheet Chpt. 15.2.4 Pg. 115.
The datasheet says a logic change on a pin will cause its corresponding INTFn bit to be set (one). It also says the flag can be cleared by writing a logical one to it.
Isn't setting the bit (one) and writing a logical 1 to it the same thing? If not, what do I write to it to set the flag to affect an interrupt?
What I want to do is set the bit by code to trigger an interrupt event. But I can't see any way of doing it.
Writing a (zero) to the bit doesn't change the bit state so I can't trigger an interrupt that way. The only thing I can think of is to set the pinMode(INT4PIN, OUTPUT) and digitalWrite(INT4PIN, LOW), to affect a logic change on the pin. This is annoying because I have to put a resistor in series to protect the pin and this may affect the circuit triggering the interrupt. This is not an elegant solution.
Is there a way to trigger an external interrupt using software only?
P.S. I have read "Why are (many) interrupt flags cleared by writing a logical 1?" from the frequently asked questions section of the Atmel AVR libc reference manual. I love how they say "The solution is simple". Not to me it's not!
ref: Smart | Connected | Secure | Microchip Technology
"The solution is simple: writing a logical 1 to it requires only a single OUT instruction, and it is clear that only this single interrupt request bit will be cleared. There is no need to perform a read-modify-write cycle (like, an SBI instruction), since all bits in these control registers are interrupt bits, and writing a logical 0 to the remaining bits (as it is done by the simple OUT instruction) will not alter them, so there is no risk of any race condition that might accidentally clear another interrupt request bit. So instead of writing
TIFR |= _BV(TOV0); /* wrong! */
simply use
TIFR = _BV(TOV0);"
Everyone seems preoccupied with clearing the flag. Nothing on how to set the bit to cause an interrupt event however.
"Why would I wan't to?" you ask. After all, external interrupts are for being triggered externally. Well... I have a D.P momentary push button switch that both switches on power to the MEGA and also triggers an interrupt on pin2/INT4. The MEGA can be switched on by various means, so when the AVR fires up the first thing it wants to know is if it has been switched on by the "interrupt switch". If so it wants to execute the ISR. This same switch may be used to fire an interrupt at any time while the MEGA is active (the very purpose of interrupts).
The MEGA is not switched on the first time the button is pressed. Pressing the button puts power to the MEGA via a mosfet and also stores a charge in a capacitor which puts a temporary voltage on pin2/INT4 for a few seconds. The MEGA powers up and immediately checks pin2. If pin2 is High it knows the button was pressed and wants to execute the ISR. The interrupt is configured "rising edge". Because of the capacitor the falling edge doesn't occur until a few seconds after the button press. I configure it as RISING because I want the ISR to execute immediately. No-one wants to press a button and wait two seconds for a response, it just doesn't inspire confidence.
But, the first time the button is pressed the MEGA is off. It can't detect the rising edge, only the falling edge when the capacitor bleeds down. "Why not configure it FALLING initially and change it to RISING later?" you ask. After power up I don't want to hang around waiting for a possible interrupt from a falling edge. I want to know if pin2 is HIGH straight away and act on it. The most elegant solution would be to flag the EIFR in software to fire the interrupt, but I can't figure out how when only the AVR can affect an interrupt by setting the bit (one). When I set the bit (one) the bloody flag is cleared!
Please tell me I'm a complete NOOB, that I clearly don't know what I'm talking about, and that YES you can set the register from software to fire an interrupt.
Cheers All.