MCP23017 Interrupts

Trying to get an interrupt to fire when i press a button on a MCP23017 chip. The interrupt is firing if i manually change the voltage on PO_12 or PO_13(these are connected to INTA and INTB on MCP23017). I can easily controll LEDs connected the ports on the mmCP23017 so it must be some configuration.

Any help?

GPB ports are all set to outputs.
GP0A TO GP3A set to outputs
GP4A TO GP7A set to inputs (conncted to buttons connected to ground).

      MuxLedsRelays = new Mcp23017(0x21, null, LoggingLevel.warning);
            // MuxLedsRelays = new Mcp23017(0x23, null);
            // MuxLedsRelays = new Mcp23017(0x32, null);
            // MuxLedsRelays = new Mcp23017(0x30, null);


            MuxLedsRelays.PinDirectionB(Pin.ALL, Direction.Output);

            MuxLedsRelays.PinDirectionA(Pin.GP0A, Direction.Output);
            MuxLedsRelays.PinDirectionA(Pin.GP1A, Direction.Output);
            MuxLedsRelays.PinDirectionA(Pin.GP2A, Direction.Output);
            MuxLedsRelays.PinDirectionA(Pin.GP3A, Direction.Output);

            MuxLedsRelays.PinDirectionA(Pin.GP4A, Direction.Input);
            MuxLedsRelays.PinDirectionA(Pin.GP5A, Direction.Input);
            MuxLedsRelays.PinDirectionA(Pin.GP6A, Direction.Input);
            MuxLedsRelays.PinDirectionA(Pin.GP7A, Direction.Input);


            MuxLedsRelays.PinPullupA(Pin.GP4A, true);
            MuxLedsRelays.PinPullupA(Pin.GP5A, true);
            MuxLedsRelays.PinPullupA(Pin.GP6A, true);
            MuxLedsRelays.PinPullupA(Pin.GP7A, true);

            MuxLedsRelays.PinInterruptOnChangeA(Pin.GP4A, true);
            MuxLedsRelays.PinInterruptOnChangeA(Pin.GP5A, true);
            MuxLedsRelays.PinInterruptOnChangeA(Pin.GP6A, true);
            MuxLedsRelays.PinInterruptOnChangeA(Pin.GP7A, true);
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace ZigmateGadgeteer
{


    public enum Direction
    {
        Output = 0x00,
        Input = 0x01,
    }

    public enum Polarity
    {
        Normal = 0x00,
        Invert = 0x01,
    }

    public enum InterruptControl
    {
        PreviousValue = 0x00,
        DefaultValue = 0x01,
    }


    public enum Pin
    {
        GP0A = 0x01,
        GP1A = 0x02,
        GP2A = 0x04,
        GP3A = 0x08,
        GP4A = 0x10,
        GP5A = 0x20,
        GP6A = 0x40,
        GP7A = 0x80,
        GP0B = 0x01,
        GP1B = 0x02,
        GP2B = 0x04,
        GP3B = 0x08,
        GP4B = 0x10,
        GP5B = 0x20,
        GP6B = 0x40,
        GP7B = 0x80,
        ALL = 0xFF,
    }

    public enum ConfigRegister
    {
        /// <summary>
        /// Sequential Operation
        /// 0 = enabled(default)
        /// 1 = disabled
        /// </summary>
        SEQOP = 0x20,

        /// <summary>
        /// SDA Slew Rate
        /// 0 = enabled(default)
        /// 1 = disabled
        /// </summary>
        DISSLW = 0x10,

        /// <summary>
        /// Hardware Address Enable for MCP23S08 SPI version only
        /// 0 = disabled(default)
        /// 1 = enabled
        /// </summary>
        HAEN = 0x08,

        /// <summary>
        /// INT pin as open-drain
        /// 0 = Active driver output(default)
        /// 1 = Open-drain output
        /// </summary>
        ODR = 0x04,

        /// <summary>
        /// INT polarity
        /// 0 = Active-low(default)
        /// 1 = Active-high
        /// </summary>
        INTPOL = 0x02,
    }

    

    /// <summary>
    /// MCP23017 pin expander
    /// </summary>
    public class Mcp23017
    {
        #region "Contructor"
        /// <summary>
        /// Reference to the I�C bus
        /// </summary>
        private I2CDevice _Device;

        // Registers for port A
        private const byte _IODIRA = 0x00;
        private const byte _IPOLA = 0x02;
        private const byte _GPINTENA = 0x04;
        private const byte _DEFVALA = 0x06;
        private const byte _INTCONA = 0x08;
        private const byte _IOCONA = 0x0a;
        private const byte _GPPUA = 0x0c;
        private const byte _INTFA = 0x0e;
        private const byte _INTCAPA = 0x10;
        private const byte _GPIOA = 0x12;
        private const byte _OLATA = 0x14;

        // Registers for port B
        private const byte _IODIRB = 0x01;
        private const byte _IPOLB = 0x03;
        private const byte _GPINTENB = 0x05;
        private const byte _DEFVALB = 0x07;
        private const byte _INTCONB = 0x09;
        private const byte _IOCONB = 0x0b;
        private const byte _GPPUB = 0x0d;
        private const byte _INTFB = 0x0f;
        private const byte _INTCAPB = 0x11;
        private const byte _GPIOB = 0x13;
        private const byte _OLATB = 0x15;

        OutputPort resetPin;
        byte[] singleCommand = new byte[1];
        byte[] writeBuffer = new byte[2];
        byte[] readBuffer = new byte[1];

        I2CDevice.I2CTransaction[] writeTrans = new I2CDevice.I2CTransaction[1];
        I2CDevice.I2CTransaction[] readTrans = new I2CDevice.I2CTransaction[2];

        LoggingLevel debugmode;
        Byte bResult;
        /// <summary>
        /// Initialises a new MCP23017 pin expander
        /// </summary>
        /// <param name="Address">The I�C address</param>
        /// <param name="ClockRateKhz">The module speed in Khz</param>
        /// <summary>
        /// Init with I2C address and optional hardware reset pin
        /// Set reset pin 6 high if not used
        /// </summary>
        /// <param name="address">0x20 to 0x27</param>
        /// <param name="resetPin">set null if not used</param>
        public Mcp23017(byte address, OutputPort resetPin, LoggingLevel _debugmode)
        {
            debugmode = _debugmode;
            this._Device = new I2CDevice(new I2CDevice.Configuration(address, 400));
            this.resetPin = resetPin;
            Init();
        }

        //public Mcp23017()
        //{
        //    this._Device = new I2CDevice(new I2CDevice.Configuration(0x41, 100));
        //    this.resetPin = null;
        //    Init();
        //}
        #endregion
        private void Init()
        {
            Reset();
            ClearInterruptA();
            ClearInterruptB();
        }

        /// <summary>
        /// Hardware or software reset
        /// </summary>
        public void Reset()
        {
            if (resetPin != null)
            {
                resetPin.Write(false);
                Thread.Sleep(5);
                resetPin.Write(true);
                Thread.Sleep(5);
            }
            else
            {
                //set default Reset values if not using hardware reset pin
                //Write(_IODIRA, 0x00);//00=OUTPUT
                Write(_IPOLA, 0x00);
                Write(_GPINTENA, 0x00);//Interupts off
                Write(_DEFVALA, 0x00);
                Write(_INTCONA, 0x00);
                Write(_IOCONA, 0x00);
                Write(_GPPUA, 0x00);
                Write(_INTFA, 0x00);
                Write(_INTCAPA, 0x00);
                Write(_GPIOA, 0x00);
                Write(_OLATA, 0x00);

                //Write(_IODIRB, 0x00);//00=OUTPUT
                Write(_IPOLB, 0x00);
                Write(_GPINTENB, 0x00);//Interupts off
                Write(_DEFVALB, 0x00);
                Write(_INTCONB, 0x00);
                Write(_IOCONB, 0x00);
                Write(_GPPUB, 0x00);
                Write(_INTFB, 0x00);
                Write(_INTCAPB, 0x00);
                Write(_GPIOB, 0x00);
                Write(_OLATB, 0x00);
            }
        }

        /// <summary>
        /// Write single register
        /// </summary>
        /// <param name="reg">Register name</param>
        /// <param name="val">Register value</param>
        public void Write(byte reg, byte val)
        {
            int written;
            writeBuffer[0] = (byte)reg;
            writeBuffer[1] = val;
            writeTrans[0] = I2CDevice.CreateWriteTransaction(writeBuffer);
            written = _Device.Execute(writeTrans, 1000);

            if (written != writeBuffer.Length)
            {
                if (debugmode >= LoggingLevel.error) Debug.Print(val + " has NOT been written to " + reg + "  I2C device[" + _Device.Config.Address + "].");
            }
            else
            {
                if (debugmode >= LoggingLevel.info) Debug.Print(val + " has been written to " + reg + "  I2C device[" + _Device.Config.Address + "].");
            }

        }

        /// <summary>
        /// Read single register
        /// </summary>
        /// <param name="reg">Register name</param>
        /// <returns>Register value</returns>
        public byte Read(byte reg)
        {
            singleCommand[0] = (byte)reg;
            readTrans[0] = I2CDevice.CreateWriteTransaction(singleCommand);
            readTrans[1] = I2CDevice.CreateReadTransaction(readBuffer);
            int resylt = _Device.Execute(readTrans, 1000);

            if (resylt > 0)
            {
                if (debugmode >= LoggingLevel.info) Program.Logit(" Read " + reg + "  I2C device[" + _Device.Config.Address + "] Result[" + readBuffer[0] + "]");
            }
            else
            {
                if (debugmode >= LoggingLevel.error) Program.Logit(" Read " + reg + "  I2C device[" + _Device.Config.Address + "] No data returned");
            }


            return readBuffer[0];
        }


        /// <summary>
        /// Write GPIO pin(s)
        /// </summary>
        /// <param name="pin">pin</param>
        /// <param name="value">value</param>
        public void WritePinA(Pin pinMask, bool value)
        {
            SetRegisterForPin(_GPIOA, pinMask, value);
        }

        public void WritePinB(Pin pinMask, bool value)
        {
            SetRegisterForPin(_GPIOB, pinMask, value);
        }
        /// <summary>
        /// Read single GPIO pin
        /// </summary>
        /// <param name="pin">pin</param>
        /// <returns>pin value</returns>
        public bool ReadPin(Pin pin)
        {
            byte current_GPIO = Read(_GPIOA);
            if ((current_GPIO & (byte)pin) > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Read GPIO pin(s)
        /// </summary>
        /// <param name="pin">pin mask</param>
        /// <returns>masked value</returns>
        public byte ReadPinsA(Pin pinMask)
        {
            byte current_GPIOA = Read(_GPIOA);
            current_GPIOA &= (byte)pinMask;

            return current_GPIOA;
        }

        /// <summary>
        /// Read GPIO pin(s)
        /// </summary>
        /// <param name="pin">pin mask</param>
        /// <returns>masked value</returns>
        public byte ReadPinsB(Pin pinMask)
        {
            byte current_GPIOB = Read(_GPIOB);
            current_GPIOB &= (byte)pinMask;

            return current_GPIOB;
        }

        /// <summary>
        /// Set pin direction mask
        /// </summary>
        /// <param name="pin">pin</param>
        /// <param name="dir">direction</param>
        public void PinDirectionA(Pin pinMask, Direction dir)
        {
            bool value = false;
            if (dir == Direction.Input)
            {
                value = true;
            }
            SetRegisterForPin(_IODIRA, pinMask, value);
        }

        public void PinDirectionB(Pin pinMask, Direction dir)
        {
            bool value = false;
            if (dir == Direction.Input)
            {
                value = true;
            }
            SetRegisterForPin(_IODIRB, pinMask, value);
        }

        /// <summary>
        /// Set pin input polarity mask
        /// </summary>
        /// <param name="pin">pin</param>
        /// <param name="pol">polarity</param>
        public void PinPolarity(Pin pinMask, Polarity pol)
        {
            bool value = false;
            if (pol == Polarity.Invert)
            {
                value = true;
            }
            SetRegisterForPin(_GPINTENA, pinMask, value);
        }

        /// <summary>
        /// Set pin interrupt on change mask
        /// </summary>
        /// <param name="pin">pin</param>
        /// <param name="value">value</param>
        public void PinInterruptOnChangeB(Pin pinMask, bool value)
        {
            SetRegisterForPin(_GPINTENB, pinMask, value);
        }

        /// <summary>
        /// Set pin interrupt on change mask
        /// </summary>
        /// <param name="pin">pin</param>
        /// <param name="value">value</param>
        public void PinInterruptOnChangeA(Pin pinMask, bool value)
        {
            SetRegisterForPin(_GPINTENA, pinMask, value);
        }

        /// <summary>
        /// Set pin mask default value to cause interrupt
        /// </summary>
        /// <param name="pin">pin</param>
        /// <param name="value">value</param>
        public void PinDefaultValueA(Pin pinMask, bool value)
        {
            SetRegisterForPin(_DEFVALA, pinMask, value);
        }

        public void PinDefaultValueB(Pin pinMask, bool value)
        {
            SetRegisterForPin(_DEFVALB, pinMask, value);
        }

        /// <summary>
        /// Set pin pullup resistor mask
        /// </summary>
        /// <param name="pin">pin</param>
        /// <param name="value">value</param>
        public void PinPullupA(Pin pinMask, bool value)
        {
            SetRegisterForPin(_GPPUA, pinMask, value);
        }


        /// <summary>
        /// Set pin pullup resistor mask
        /// </summary>
        /// <param name="pin">pin</param>
        /// <param name="value">value</param>
        public void PinPullupB(Pin pinMask, bool value)
        {
            SetRegisterForPin(_GPPUB, pinMask, value);
        }

        /// <summary>
        /// Set interrupt compare mode
        /// </summary>
        /// <param name="pinMask">pins</param>
        /// <param name="ic">mode</param>
        public void PinInterruptControlA(Pin pinMask, InterruptControl ic)
        {
            bool value = false;
            if (ic == InterruptControl.DefaultValue)
            {
                value = true;
            }
            SetRegisterForPin(_INTCONA, pinMask, value);
        }

        public void PinInterruptControlB(Pin pinMask, InterruptControl ic)
        {
            bool value = false;
            if (ic == InterruptControl.DefaultValue)
            {
                value = true;
            }
            SetRegisterForPin(_INTCONB, pinMask, value);
        }

        /// <summary>
        /// Set pin value mask
        /// </summary>
        /// <param name="reg">register</param>
        /// <param name="pin">pin</param>
        /// <param name="value">value</param>
        private void SetRegisterForPin(byte reg, Pin pinMask, bool value)
        {
            byte current = Read(reg);
            if (value)
            {
                current |= (byte)pinMask;
            }
            else
            {
                current &= (byte)((int)~pinMask);
            }
            Write(reg, current);
        }

        public void WritePinsB(byte bvalue)
        {
            byte current = Read(_GPIOB);
            //  if (value)
            //  {
            current &= (byte)bvalue;
            // }
            //else
            //{
            //    current &= (byte)((int)~pinMask);
            //}
            Write(_GPIOB, current);
        }



        /// <summary>
        /// Set configuration
        /// </summary>
        /// <param name="cr">config</param>
        public void SetConfigRegister(ConfigRegister cr)
        {
          Write(_IOCONA, (byte)cr);
        }

        /// <summary>
        /// Clear INTF by reading INTCAP
        /// </summary>
        public void ClearInterruptA()
        {
          bResult=  Read(_INTCAPA);

          if (debugmode >= LoggingLevel.error) Program.Logit("ClearInterruptA[" + bResult + "]");
        }

        public void ClearInterruptB()
        {
            bResult = Read(_INTCAPB);

            if (debugmode >= LoggingLevel.error) Program.Logit("ClearInterruptB[" + bResult + "]");
        }
    }
}

Problem solved…had the switch wired incorrectly!