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 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?

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 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