0

I'm trying to read interrupt changes from a MCP23017 board using pigpio but i'm not getting any notification... what seems that i do not know is the initialize procedures that i need to do (looking into the documentation http://ww1.microchip.com/downloads/en/devicedoc/20001952c.pdf it seems that i'm not using the correct values...).

I'm using B side for inputs and A for outputs:

i2cWriteByteData(i2cHandle, IODIRB, 0xFF); // inputs
i2cWriteByteData(i2cHandle, IODIRA, 0x00); // outputs

then i try to set the interrupt state (that it seems to be wrong), but i'm copied from 'I2C Sonar' example from http://abyz.me.uk/rpi/pigpio/examples.html

i2cWriteByteData(i2cHandle, GPINTENB, 0x00); // Disable.
i2cWriteByteData(i2cHandle, DEFVALB, 0x00) ; // N/A.
i2cWriteByteData(i2cHandle, INTCONB, 0x00) ; // On change.

and then registe the handler to read the changes:

gpioSetMode(ALERTPIN, PI_INPUT); /* start capacitor recharge */
gpioSetISRFuncEx(ALERTPIN, EITHER_EDGE, 0, alert, nullptr); /* call alert when state changes */

So my question is what I'm missing that my alert function is never called when states change (strangely it is called when i do a dump on the console (sudo i2cdump -y 1 0x20)

Other question is are my defines correct? why are two sets of values (Address IOCON.BANK = 1 and 0)? what are the addresses for MCP23017? (i'm using Address IOCON.BANK = 0):

#define IODIRA    0x00
#define IODIRB    0x01
#define IPOLA     0x02
#define IPOLB     0x03
#define GPINTENA  0x04
#define GPINTENB  0x05
#define DEFVALA   0x06
#define DEFVALB   0x07
#define INTCONA   0x08
#define INTCONB   0x09
#define IOCONA    0x0A
#define IOCONB    0x0B
#define GPPUA     0x0C
#define GPPUB     0x0D
#define INTFA     0x0E
#define INTFB     0x0F
#define INTCAPA   0x10
#define INTCAPB   0x11
#define GPIOA     0x12
#define GPIOB     0x13
#define OLATA     0x14
#define OLATB     0x15

#define ALERTPIN 26

Update:

Next i show all the code that I perform and after read the documentation I think that i'm doing everything correct, but it seems that i'm missing some initialization... and strangely the GPIOA read when input button connected to GPA0 is pressed the value is 255 (0xff) and if is not press then is 0... strange it should be 1 when pressed right?

void estimulateMCP23017(unsigned i2cAddr=0x20,unsigned i2cBus=1){
    //open i2c MCP23017
    int i2cHandle = i2cOpen(i2cBus, i2cAddr, 0);
    //open is with success if is >=0
    if(i2cHandle>=0){
        //IODIR: I/O DIRECTION REGISTER (ADDR 0x00)
        //1 = Pin is configured as an input.
        //0 = Pin is configured as an output
        //we can set each separately if we want
        //set side A as output (0)
        i2cWriteByteData(i2cHandle, IODIRA, 0xFF); // A is inputs
        //set side B as input (1)
        i2cWriteByteData(i2cHandle, IODIRB, 0x00); // B is outputs

        //turn all outputs to on (pins 0 to 7 is the bit high in 0x00-0xFF)
        i2cWriteByteData(i2cHandle, OLATA, 0x00);
        i2cWriteByteData(i2cHandle, OLATB, 0xFF);

        //now listen for changes on side (B)
        // General purpose I/O interrupt-on-change bits <7:0>
        //1 = Enables GPIO input pin for interrupt-on-change event.
        //0 = Disables GPIO input pin for interrupt-on-change event.
        i2cWriteByteData(i2cHandle, GPINTENA, 0xFF); // Enable all
        i2cWriteByteData(i2cHandle, GPINTENB, 0x00); // disable
        //Sets the compare value for pins configured for interrupt-on-change from defaults <7:0>
        //If the associated pin level is the opposite from the register bit, an interrupt occurs
        i2cWriteByteData(i2cHandle, DEFVALA, 0x00); // does not matter
        i2cWriteByteData(i2cHandle, DEFVALB, 0x00); // does not matter
        // Controls how the associated pin value is compared for interrupt-on-change <7:0>
        //1 = Pin value is compared against the associated bit in the DEFVAL register.
        //0 = Pin value is compared against the previous pin value.
        i2cWriteByteData(i2cHandle, INTCONA, 0x00) ; // On change.
        i2cWriteByteData(i2cHandle, INTCONB, 0x00) ; // does not matter.

        cout << "waiting for changes...(input value: "<<i2cReadByteData(i2cHandle, GPIOA)<<")\n";

        gpioSetMode(ALERTPIN, PI_INPUT); /* set alert pin as input */
        gpioSetISRFuncEx(ALERTPIN, EITHER_EDGE, 0, alert, nullptr); /* call alert when state changes */

        cin.get();
        i2cClose(i2cHandle);
    }
}
Nuno
  • 1,910
  • 2
  • 21
  • 33

1 Answers1

0

Since Bank A is your input, you should use:

i2cWriteByteData(i2cHandle, GPINTENA, 0xFF); // Enable.
i2cWriteByteData(i2cHandle, INTCONA, 0x00) ; // On change.

Your defines look right. The MCP23017 has two different modes of addressing the registers. The mode is set using the IOCON.BANK flag. Just never touch that bit, there's no reason to do so.

PMF
  • 14,535
  • 3
  • 23
  • 49
  • Hi PMF, thank you for the reply by why are you saying that Bank A is the input? is this not the correct way of setting Bank B as input: 'i2cWriteByteData(i2cHandle, IODIRB, 0xFF);'? – Nuno Jun 30 '20 at 10:22