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

Dependents:   MCP23009tst

Committer:
wbeaumont
Date:
Fri Jun 03 12:40:49 2016 +0000
Revision:
0:d829b4edd564
Child:
1:9146d773a5a3
initial version not tested with hw

Who changed what in which revision?

UserRevisionLine numberNew 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 0:d829b4edd564 5 #define VERSION_MCP23009_SRC "0.10"
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 0:d829b4edd564 32 int MCP23009::status( int pinnr){
wbeaumont 0:d829b4edd564 33 int result=0;
wbeaumont 0:d829b4edd564 34 data[0]=GPIO;
wbeaumont 0:d829b4edd564 35 result= _i2c_interface->write(_device_address, data,1); // set reg
wbeaumont 0:d829b4edd564 36 if ( result ) return -1;
wbeaumont 0:d829b4edd564 37 char rb[0];
wbeaumont 0:d829b4edd564 38 result = _i2c_interface->read(_device_address,rb,1); // read the current status
wbeaumont 0:d829b4edd564 39 if ( result ) return -2;
wbeaumont 0:d829b4edd564 40 if ( pinnr != 8) {
wbeaumont 0:d829b4edd564 41 rb[0] = rb[0] >> pinnr;
wbeaumont 0:d829b4edd564 42 rb[0] = 1 &rb[0];
wbeaumont 0:d829b4edd564 43 }
wbeaumont 0:d829b4edd564 44 return rb[0];
wbeaumont 0:d829b4edd564 45 }
wbeaumont 0:d829b4edd564 46
wbeaumont 0:d829b4edd564 47 int MCP23009::set( int pinnr , int value){
wbeaumont 0:d829b4edd564 48 int result=0;
wbeaumont 0:d829b4edd564 49 data[0]=OLAT;
wbeaumont 0:d829b4edd564 50 if ( pinnr != 8) {
wbeaumont 0:d829b4edd564 51 bool vb=false;
wbeaumont 0:d829b4edd564 52 if ( value > 0) {vb=true;}
wbeaumont 0:d829b4edd564 53 result=pinmanipulation( vb , pinnr);
wbeaumont 0:d829b4edd564 54 }
wbeaumont 0:d829b4edd564 55 else {
wbeaumont 0:d829b4edd564 56 data[1]= (unsigned char) value ;
wbeaumont 0:d829b4edd564 57 result = _i2c_interface->write(_device_address, data,2);
wbeaumont 0:d829b4edd564 58 }
wbeaumont 0:d829b4edd564 59 return result;
wbeaumont 0:d829b4edd564 60 }
wbeaumont 0:d829b4edd564 61
wbeaumont 0:d829b4edd564 62 int MCP23009::set_as_input(int pinnr,int pullup, int polarity ){
wbeaumont 0:d829b4edd564 63 return set_io_pin(true , pinnr, pullup, polarity );
wbeaumont 0:d829b4edd564 64 }
wbeaumont 0:d829b4edd564 65 int MCP23009::set_as_output(int pinnr,int pullup, int polarity ){
wbeaumont 0:d829b4edd564 66 return set_io_pin(false , pinnr, pullup, polarity );
wbeaumont 0:d829b4edd564 67 }
wbeaumont 0:d829b4edd564 68
wbeaumont 0:d829b4edd564 69 int MCP23009::set_io_pin(bool input ,int pinnr,int pullup, int polarity ){
wbeaumont 0:d829b4edd564 70 int result=0;
wbeaumont 0:d829b4edd564 71 if ( pinnr >8 || pinnr < 0 ) return -20;
wbeaumont 0:d829b4edd564 72
wbeaumont 0:d829b4edd564 73 data[0]=IODIR;
wbeaumont 0:d829b4edd564 74 result=pinmanipulation( input , pinnr);
wbeaumont 0:d829b4edd564 75 if ( result ) return result;
wbeaumont 0:d829b4edd564 76 if (pullup >= 0) {
wbeaumont 0:d829b4edd564 77 data[0]=GPPU;
wbeaumont 0:d829b4edd564 78 bool pullup_b=false;
wbeaumont 0:d829b4edd564 79 if ( pullup > 0) pullup_b =true;
wbeaumont 0:d829b4edd564 80 result=pinmanipulation( pullup_b , pinnr);
wbeaumont 0:d829b4edd564 81 if ( result ) return result;
wbeaumont 0:d829b4edd564 82 }
wbeaumont 0:d829b4edd564 83 if (polarity >= 0) {
wbeaumont 0:d829b4edd564 84 data[0]=IPOL;
wbeaumont 0:d829b4edd564 85 bool pol_b=false;
wbeaumont 0:d829b4edd564 86 if ( polarity > 0) pol_b =true;
wbeaumont 0:d829b4edd564 87 result=pinmanipulation( pol_b , pinnr);
wbeaumont 0:d829b4edd564 88 if ( result ) return result;
wbeaumont 0:d829b4edd564 89 }
wbeaumont 0:d829b4edd564 90 return 0;
wbeaumont 0:d829b4edd564 91 }
wbeaumont 0:d829b4edd564 92
wbeaumont 0:d829b4edd564 93
wbeaumont 0:d829b4edd564 94 int MCP23009::pinmanipulation ( bool active , int pinnr ){
wbeaumont 0:d829b4edd564 95 int result=-10;
wbeaumont 0:d829b4edd564 96 if (pinnr < 8 ) {
wbeaumont 0:d829b4edd564 97 result= _i2c_interface->write(_device_address, data,1); // set to ioreg
wbeaumont 0:d829b4edd564 98 if ( result ) return -1;
wbeaumont 0:d829b4edd564 99 char rb[0];
wbeaumont 0:d829b4edd564 100 result = _i2c_interface->read(_device_address, rb,1); // read the current status
wbeaumont 0:d829b4edd564 101 if ( result ) return -2;
wbeaumont 0:d829b4edd564 102 data[1]= 1<<pinnr;
wbeaumont 0:d829b4edd564 103 if ( active ) { data[1] |= rb[0]; } // new reg value for pinnr input
wbeaumont 0:d829b4edd564 104 else { data[1] = ~data[1];
wbeaumont 0:d829b4edd564 105 data[1] &= rb[0]; // new reg value for pinnr ouput
wbeaumont 0:d829b4edd564 106 }
wbeaumont 0:d829b4edd564 107 if ( rb[0] != data[1]) { // only write if different
wbeaumont 0:d829b4edd564 108 result=_i2c_interface->write(_device_address, data,2);
wbeaumont 0:d829b4edd564 109 }
wbeaumont 0:d829b4edd564 110 }
wbeaumont 0:d829b4edd564 111 else { // change all pins
wbeaumont 0:d829b4edd564 112 if ( active) data[1]=0xFF; else data[1]=0;
wbeaumont 0:d829b4edd564 113 result=_i2c_interface->write(_device_address, data,2);
wbeaumont 0:d829b4edd564 114 }
wbeaumont 0:d829b4edd564 115 return result;
wbeaumont 0:d829b4edd564 116 }
wbeaumont 0:d829b4edd564 117