MCP23017 register not working?!?

Here is a snippet of my code below. I have a single MCP23017 that is using Port A and B to read a switch matrix of 8x8 or 64 buttons. When I set the INTCONA register to 0x00 (interrupt on change from previous port state) everything works as expected. But when I set INTCONA to 0xFF (interrupt on change from DEFVAL) the interrupt only triggers once and will never reset. Yes, I am resetting the interrupt by reading INTCAPA. What is going on? How is this possible? Is anything blatantly wrong with the code I have below?

All help is MUCH appreciated. This is driving me batty.

void setup(){
  Serial.begin(9600); //beging serial comm at 9600 bits/s
  Wire.begin(); //wake up the i2c bus
  Serial.println("Boot-up sequence");
  expanderWriteBoth (I2C_TOGS, IOCON, 0b00000000); 

  expanderWrite(I2C_TOGS, IODIRA, 0x01); //set port A to inputs

  expanderWrite(I2C_TOGS, IODIRB, 0x00); //set port B to outputs

  expanderWrite(I2C_TOGS, GPIOB, 0x00); //ground all of port B

  expanderWrite(I2C_TOGS, IOPOLA, 0x00); //set polarity of port A to normal
  expanderWrite(I2C_TOGS, GPINTENA, 0xFF); //set port A to interrupt on change

  expanderWrite(I2C_TOGS, DEFVALA, 0xFF); //default value for port A to read, all pins high
  expanderWrite(I2C_TOGS, GPPUA, 0xFF); // enable pull up resistors on port A so that it is always reading high unless grounded

  expanderWrite(I2C_TOGS, INTCONA, 0xFF); // interrupt on change from DEFVAL


  // no interrupt yet
  keyPressed = false;

  // read from interrupt capture addr A to clear it (reading resets the addr interrupt)
  expanderRead(I2C_TOGS, INTCAPA);

  // pin 19 of MCP23017 is plugged into D2 of the Arduino which is interrupt 0
  attachInterrupt(0, keypress, FALLING);
  Serial.println("Initializing LCD...");
  initializeDisplay(); // initialize the display
  Serial.println("Initializing Cue Statuses...");
  initializeCues(cue);  //initialize cues


// ISR
void keypress(){
  keyPressed = true;

// Main Program Loop
void loop(){
  unsigned long i;
  // some imaddrant calculations here ...
  for (i = 0; i < 0x7FFFF; i++) {

  // was there an interrupt?
  if (keyPressed){

  //updateDisplay(); if(displayData);

  // read Serial port
  /*if(Serial.available() > 0){
   char command =; //read the data
   delay(100); // wait for entire message to be received

   void fireSelectedCue(int cue){

// Write to both addrs of the expander
void expanderWriteBoth (const byte addr, const byte reg, const byte data ) {
  Wire.beginTransmission (addr);
  Wire.write(data);  // addr A
  Wire.write(data);  // addr B

// called from main loop when we know we had an interrupt
void handleKeypress ()
  Serial.println("HANDLE KEYPRESS");
  unsigned int keyValue = 0;
  byte readData;
  int col;
  boolean flag = false;
  byte bitData = 0x00;
  delay(100);  // de-bounce before we re-enable interrupts

 // readData = expanderRead(I2C_TOGS, GPIOA);

  //expanderRead (INTCAPA) << 8;    // read value at time of interrupt
  for(int i=0; i<8; i++){
    expanderWrite(I2C_TOGS, GPIOB, bitSet(bitData,i));
    readData = expanderRead(I2C_TOGS, GPIOA);
    if(readData != 0 && !flag){

    expanderWrite(I2C_TOGS, GPIOB, 0x00);


  if(readData != 0x00){
    readData |= col;
    //  Serial.println(readData, DEC);
    readData = 0x00; 

  //expanderWrite(I2C_TOGS, GPIOB, 0x00);

  expanderRead(I2C_TOGS, INTCAPA); //reset the interrupt capture on addr A

    keyPressed = false;  // ready for next time through the interrupt service routine


After further investigation, I think I found what is causing the interrupt to not reset.

If I hold the button down longer than the duration of the switch debounce line "delay(xxx), then the interrupt will never reset because it is essentially resetting the interrupt to trigger while the trigger condition is true!

What can i do to combat this? Any suggestions? I want to user to be able to hold the button down as long as they want but have the interrupt still be able to reset for another button to get pressed later.


Solved the problem! The interrupt handling function was not being called again because the "keypress"flag was never allowed to be set to true and then would never enter the conditional in the main loop.