MCP23009 is a general IO I2C chip . This lib provide higher level interface ( set pin value, set io modes etc ) without need to have knowledge of the I2C registers
mcp23009.cpp@1:9146d773a5a3, 2016-06-03 (annotated)
- Committer:
- wbeaumont
- Date:
- Fri Jun 03 16:01:45 2016 +0000
- Revision:
- 1:9146d773a5a3
- Parent:
- 0:d829b4edd564
added more functions , tested with hardware using n FRDM_KL05Z)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wbeaumont | 0:d829b4edd564 | 1 | #include "mcp23009.h" |
wbeaumont | 0:d829b4edd564 | 2 | //#include "mbed.h" // should not be in only for printf debug ? |
wbeaumont | 0:d829b4edd564 | 3 | |
wbeaumont | 0:d829b4edd564 | 4 | |
wbeaumont | 1:9146d773a5a3 | 5 | #define VERSION_MCP23009_SRC "0.20" |
wbeaumont | 0:d829b4edd564 | 6 | |
wbeaumont | 0:d829b4edd564 | 7 | // definition registers |
wbeaumont | 0:d829b4edd564 | 8 | |
wbeaumont | 0:d829b4edd564 | 9 | #define IODIR 0 |
wbeaumont | 0:d829b4edd564 | 10 | #define IPOL 1 |
wbeaumont | 0:d829b4edd564 | 11 | #define GPINTEN 2 |
wbeaumont | 0:d829b4edd564 | 12 | #define DEFVAL 3 |
wbeaumont | 0:d829b4edd564 | 13 | #define INTCON 4 |
wbeaumont | 0:d829b4edd564 | 14 | #define IOCON 5 |
wbeaumont | 0:d829b4edd564 | 15 | #define GPPU 6 |
wbeaumont | 0:d829b4edd564 | 16 | #define INTF 7 |
wbeaumont | 0:d829b4edd564 | 17 | #define INTCAP 8 |
wbeaumont | 0:d829b4edd564 | 18 | #define GPIO 9 |
wbeaumont | 0:d829b4edd564 | 19 | #define OLAT 10 |
wbeaumont | 0:d829b4edd564 | 20 | |
wbeaumont | 0:d829b4edd564 | 21 | MCP23009::MCP23009(I2CInterface* i2cinterface, int device_address_bits ): |
wbeaumont | 0:d829b4edd564 | 22 | getVersion( VERSION_MCP23009_HDR,VERSION_MCP23009_SRC, __TIME__, __DATE__),_i2c_interface(i2cinterface) { |
wbeaumont | 0:d829b4edd564 | 23 | int _adrbytes= device_address_bits & 7; |
wbeaumont | 0:d829b4edd564 | 24 | // Assemble the full I2C device address. |
wbeaumont | 0:d829b4edd564 | 25 | _device_address = 0x40; // Prime the full device address with the device code. |
wbeaumont | 0:d829b4edd564 | 26 | _device_address |= (_adrbytes<<1); |
wbeaumont | 0:d829b4edd564 | 27 | |
wbeaumont | 0:d829b4edd564 | 28 | data[0]=IOCON; data[1]=0x20; // set no increase addr pointer, all intterupt off |
wbeaumont | 0:d829b4edd564 | 29 | _i2c_interface->write(_device_address, data,2); |
wbeaumont | 0:d829b4edd564 | 30 | } |
wbeaumont | 0:d829b4edd564 | 31 | |
wbeaumont | 1:9146d773a5a3 | 32 | int MCP23009::outp_status( int pinnr){ |
wbeaumont | 1:9146d773a5a3 | 33 | return status_gen(pinnr,OLAT); |
wbeaumont | 1:9146d773a5a3 | 34 | } |
wbeaumont | 1:9146d773a5a3 | 35 | |
wbeaumont | 0:d829b4edd564 | 36 | int MCP23009::status( int pinnr){ |
wbeaumont | 1:9146d773a5a3 | 37 | return status_gen(pinnr,GPIO); |
wbeaumont | 1:9146d773a5a3 | 38 | } |
wbeaumont | 1:9146d773a5a3 | 39 | |
wbeaumont | 1:9146d773a5a3 | 40 | int MCP23009::status_gen( int pinnr , char reg){ |
wbeaumont | 0:d829b4edd564 | 41 | int result=0; |
wbeaumont | 1:9146d773a5a3 | 42 | data[0]=reg; |
wbeaumont | 0:d829b4edd564 | 43 | result= _i2c_interface->write(_device_address, data,1); // set reg |
wbeaumont | 0:d829b4edd564 | 44 | if ( result ) return -1; |
wbeaumont | 1:9146d773a5a3 | 45 | char rb[1]; |
wbeaumont | 0:d829b4edd564 | 46 | result = _i2c_interface->read(_device_address,rb,1); // read the current status |
wbeaumont | 0:d829b4edd564 | 47 | if ( result ) return -2; |
wbeaumont | 0:d829b4edd564 | 48 | if ( pinnr != 8) { |
wbeaumont | 0:d829b4edd564 | 49 | rb[0] = rb[0] >> pinnr; |
wbeaumont | 0:d829b4edd564 | 50 | rb[0] = 1 &rb[0]; |
wbeaumont | 0:d829b4edd564 | 51 | } |
wbeaumont | 0:d829b4edd564 | 52 | return rb[0]; |
wbeaumont | 0:d829b4edd564 | 53 | } |
wbeaumont | 0:d829b4edd564 | 54 | |
wbeaumont | 0:d829b4edd564 | 55 | int MCP23009::set( int pinnr , int value){ |
wbeaumont | 0:d829b4edd564 | 56 | int result=0; |
wbeaumont | 0:d829b4edd564 | 57 | data[0]=OLAT; |
wbeaumont | 0:d829b4edd564 | 58 | if ( pinnr != 8) { |
wbeaumont | 0:d829b4edd564 | 59 | bool vb=false; |
wbeaumont | 0:d829b4edd564 | 60 | if ( value > 0) {vb=true;} |
wbeaumont | 0:d829b4edd564 | 61 | result=pinmanipulation( vb , pinnr); |
wbeaumont | 0:d829b4edd564 | 62 | } |
wbeaumont | 0:d829b4edd564 | 63 | else { |
wbeaumont | 0:d829b4edd564 | 64 | data[1]= (unsigned char) value ; |
wbeaumont | 0:d829b4edd564 | 65 | result = _i2c_interface->write(_device_address, data,2); |
wbeaumont | 0:d829b4edd564 | 66 | } |
wbeaumont | 0:d829b4edd564 | 67 | return result; |
wbeaumont | 0:d829b4edd564 | 68 | } |
wbeaumont | 0:d829b4edd564 | 69 | |
wbeaumont | 0:d829b4edd564 | 70 | int MCP23009::set_as_input(int pinnr,int pullup, int polarity ){ |
wbeaumont | 0:d829b4edd564 | 71 | return set_io_pin(true , pinnr, pullup, polarity ); |
wbeaumont | 0:d829b4edd564 | 72 | } |
wbeaumont | 0:d829b4edd564 | 73 | int MCP23009::set_as_output(int pinnr,int pullup, int polarity ){ |
wbeaumont | 0:d829b4edd564 | 74 | return set_io_pin(false , pinnr, pullup, polarity ); |
wbeaumont | 0:d829b4edd564 | 75 | } |
wbeaumont | 0:d829b4edd564 | 76 | |
wbeaumont | 0:d829b4edd564 | 77 | int MCP23009::set_io_pin(bool input ,int pinnr,int pullup, int polarity ){ |
wbeaumont | 0:d829b4edd564 | 78 | int result=0; |
wbeaumont | 0:d829b4edd564 | 79 | if ( pinnr >8 || pinnr < 0 ) return -20; |
wbeaumont | 0:d829b4edd564 | 80 | |
wbeaumont | 0:d829b4edd564 | 81 | data[0]=IODIR; |
wbeaumont | 0:d829b4edd564 | 82 | result=pinmanipulation( input , pinnr); |
wbeaumont | 0:d829b4edd564 | 83 | if ( result ) return result; |
wbeaumont | 0:d829b4edd564 | 84 | if (pullup >= 0) { |
wbeaumont | 0:d829b4edd564 | 85 | data[0]=GPPU; |
wbeaumont | 0:d829b4edd564 | 86 | bool pullup_b=false; |
wbeaumont | 0:d829b4edd564 | 87 | if ( pullup > 0) pullup_b =true; |
wbeaumont | 0:d829b4edd564 | 88 | result=pinmanipulation( pullup_b , pinnr); |
wbeaumont | 0:d829b4edd564 | 89 | if ( result ) return result; |
wbeaumont | 0:d829b4edd564 | 90 | } |
wbeaumont | 0:d829b4edd564 | 91 | if (polarity >= 0) { |
wbeaumont | 0:d829b4edd564 | 92 | data[0]=IPOL; |
wbeaumont | 0:d829b4edd564 | 93 | bool pol_b=false; |
wbeaumont | 0:d829b4edd564 | 94 | if ( polarity > 0) pol_b =true; |
wbeaumont | 0:d829b4edd564 | 95 | result=pinmanipulation( pol_b , pinnr); |
wbeaumont | 0:d829b4edd564 | 96 | if ( result ) return result; |
wbeaumont | 0:d829b4edd564 | 97 | } |
wbeaumont | 0:d829b4edd564 | 98 | return 0; |
wbeaumont | 0:d829b4edd564 | 99 | } |
wbeaumont | 0:d829b4edd564 | 100 | |
wbeaumont | 0:d829b4edd564 | 101 | |
wbeaumont | 0:d829b4edd564 | 102 | int MCP23009::pinmanipulation ( bool active , int pinnr ){ |
wbeaumont | 0:d829b4edd564 | 103 | int result=-10; |
wbeaumont | 0:d829b4edd564 | 104 | if (pinnr < 8 ) { |
wbeaumont | 0:d829b4edd564 | 105 | result= _i2c_interface->write(_device_address, data,1); // set to ioreg |
wbeaumont | 0:d829b4edd564 | 106 | if ( result ) return -1; |
wbeaumont | 1:9146d773a5a3 | 107 | char rb[1]; |
wbeaumont | 0:d829b4edd564 | 108 | result = _i2c_interface->read(_device_address, rb,1); // read the current status |
wbeaumont | 0:d829b4edd564 | 109 | if ( result ) return -2; |
wbeaumont | 0:d829b4edd564 | 110 | data[1]= 1<<pinnr; |
wbeaumont | 0:d829b4edd564 | 111 | if ( active ) { data[1] |= rb[0]; } // new reg value for pinnr input |
wbeaumont | 0:d829b4edd564 | 112 | else { data[1] = ~data[1]; |
wbeaumont | 0:d829b4edd564 | 113 | data[1] &= rb[0]; // new reg value for pinnr ouput |
wbeaumont | 0:d829b4edd564 | 114 | } |
wbeaumont | 0:d829b4edd564 | 115 | if ( rb[0] != data[1]) { // only write if different |
wbeaumont | 0:d829b4edd564 | 116 | result=_i2c_interface->write(_device_address, data,2); |
wbeaumont | 0:d829b4edd564 | 117 | } |
wbeaumont | 0:d829b4edd564 | 118 | } |
wbeaumont | 0:d829b4edd564 | 119 | else { // change all pins |
wbeaumont | 0:d829b4edd564 | 120 | if ( active) data[1]=0xFF; else data[1]=0; |
wbeaumont | 0:d829b4edd564 | 121 | result=_i2c_interface->write(_device_address, data,2); |
wbeaumont | 0:d829b4edd564 | 122 | } |
wbeaumont | 0:d829b4edd564 | 123 | return result; |
wbeaumont | 0:d829b4edd564 | 124 | } |
wbeaumont | 0:d829b4edd564 | 125 |