// ext_int.pde - Arduino, for A Hilaire
//
// Illustrates the use of an External Interrupt.
//
// Normally Pin3 and Pin2 are open.  When Pin3 is broght to GRD
// LED in Pin5 winks.  When Pin2 is brought low, the LED on Pin4 winks.
//
//  ----- Pin3      Pin5 --330-->|--- GRD
//  ----- Pin2      Pin4 --330-->|--- GRD
//
// copyright, P H Anderson, April 12, '10

#include <avr\interrupt.h>
#include <avr\io.h>

volatile int int0_flag;
volatile int int1_flag;

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#define TRUE 1
#define FALSE 0

#define SUCCESS 1
#define FAILURE 0

ISR(INT0_vect)
{
    int0_flag = TRUE;    
}


ISR(INT1_vect)
{
    int1_flag = TRUE;    
}

void setup()
{

   delay(5000);
   Serial.begin(9600);
               
   DDRD = DDRD | B00110000; // LEDs on 4 and 5
   PORTD = 0x00; // turn off the LEDs
   
   DDRD = DDRD & B11110011; // make terms 2 and 3 inputs
   PORTD = PORTD | B00001100; // activate pullup
   
   EICRA = B00001010; // configure both for falling
   EIMSK = B00000011; // mask for INT1 and INT0
   
   int1_flag = FALSE;
   int0_flag = FALSE;  
}

void loop()
{   
    while(1)
    {
       sei();
       if(int1_flag)
       {
           cbi(EIMSK, 1); // no more interrupts
           cbi(EIFR, 1);  // clear any already there
           wink_LED(5);
           sbi(EIMSK, 1); // enable
           int1_flag = FALSE;
       }
       else if (int0_flag)
       {
           cbi(EIMSK, 0);
           cbi(EIFR, 0);
           wink_LED(4);
           sbi(EIMSK, 0);
           int0_flag = FALSE;           
       }
    }
}

void wink_LED(byte b)
{
   sbi(PORTD, b);
//   print_registers();
   delay(100);
   cbi(PORTD, b);
//   print_registers();
   delay(100);
}
     
void print_registers(void)
{
   // For debugging.  
   Serial.println();
   Serial.print("DDRD ");
   Serial.println(DDRD, HEX);
   Serial.print("PORTD ");
   Serial.println(PORTD, HEX);
   
   Serial.print("EICRA ");
   Serial.println(EICRA, HEX);   
}