A library for the Microchip MCP23008 I2C 8-bit I/O expander. Uses an external I2C object in case you are sharing the bus with other devices.

Fork of MCP23008 by Daniel Wyatt

Committer:
antonio_actus
Date:
Wed Aug 24 18:09:39 2016 +0000
Revision:
2:d9beb7a97ff3
Parent:
1:3bda347154e6
Renamed params info

Who changed what in which revision?

UserRevisionLine numberNew contents of line
antonio_actus 1:3bda347154e6 1 #include "MCP23008_I2C.hpp"
antonio_actus 1:3bda347154e6 2
antonio_actus 1:3bda347154e6 3 namespace {
antonio_actus 1:3bda347154e6 4 //const uint8_t MCP23008_ADDRESS = 0x40;
antonio_actus 1:3bda347154e6 5
antonio_actus 1:3bda347154e6 6 /* MCP23008 registers */
antonio_actus 1:3bda347154e6 7 const uint8_t IODIR = 0x00;
antonio_actus 1:3bda347154e6 8 const uint8_t IPOL = 0x01;
antonio_actus 1:3bda347154e6 9 const uint8_t GPINTEN = 0x02;
antonio_actus 1:3bda347154e6 10 const uint8_t DEFVAL = 0x03;
antonio_actus 1:3bda347154e6 11 const uint8_t INTCON = 0x04;
antonio_actus 1:3bda347154e6 12 const uint8_t IOCON = 0x05;
antonio_actus 1:3bda347154e6 13 const uint8_t GPPU = 0x06;
antonio_actus 1:3bda347154e6 14 const uint8_t INTF = 0x07;
antonio_actus 1:3bda347154e6 15 const uint8_t INTCAP = 0x08;
antonio_actus 1:3bda347154e6 16 const uint8_t GPIO = 0x09;
antonio_actus 1:3bda347154e6 17 const uint8_t OLAT = 0x0A;
antonio_actus 1:3bda347154e6 18 };
antonio_actus 1:3bda347154e6 19
antonio_actus 1:3bda347154e6 20 MCP23008_I2C::MCP23008_I2C ( I2C *i2c, char deviceAddress )
antonio_actus 1:3bda347154e6 21 : _i2c(i2c) {
antonio_actus 1:3bda347154e6 22 _slaveAddress = deviceAddress & 0xFE;
antonio_actus 1:3bda347154e6 23
antonio_actus 1:3bda347154e6 24 // Setup the I2C bus
antonio_actus 1:3bda347154e6 25 // The max bitrate for PCF8574 is 100kbit, the max bitrate for MCP23008 is 400kbit,
antonio_actus 1:3bda347154e6 26 _i2c->frequency(100000);
antonio_actus 1:3bda347154e6 27 reset ();
antonio_actus 1:3bda347154e6 28 }
antonio_actus 1:3bda347154e6 29
antonio_actus 1:3bda347154e6 30 void MCP23008_I2C::set_input_pins ( uint8_t pins ) {
antonio_actus 1:3bda347154e6 31 uint8_t value = read_register ( IODIR );
antonio_actus 1:3bda347154e6 32 write_register ( IODIR, value | pins );
antonio_actus 1:3bda347154e6 33 }
antonio_actus 1:3bda347154e6 34
antonio_actus 1:3bda347154e6 35 void MCP23008_I2C::set_output_pins ( uint8_t pins ) {
antonio_actus 1:3bda347154e6 36 uint8_t value = read_register ( IODIR );
antonio_actus 1:3bda347154e6 37 write_register ( IODIR, value & ~pins );
antonio_actus 1:3bda347154e6 38 }
antonio_actus 1:3bda347154e6 39
antonio_actus 1:3bda347154e6 40 void MCP23008_I2C::write_outputs ( uint8_t values ) {
antonio_actus 1:3bda347154e6 41 write_register ( GPIO, values );
antonio_actus 1:3bda347154e6 42 }
antonio_actus 1:3bda347154e6 43
antonio_actus 1:3bda347154e6 44 uint8_t MCP23008_I2C::read_outputs () {
antonio_actus 1:3bda347154e6 45 return read_register ( OLAT );
antonio_actus 1:3bda347154e6 46 }
antonio_actus 1:3bda347154e6 47
antonio_actus 1:3bda347154e6 48 uint8_t MCP23008_I2C::read_inputs () {
antonio_actus 1:3bda347154e6 49 return read_register ( GPIO );
antonio_actus 1:3bda347154e6 50 }
antonio_actus 1:3bda347154e6 51
antonio_actus 1:3bda347154e6 52 void MCP23008_I2C::set_input_polarity ( uint8_t values ) {
antonio_actus 1:3bda347154e6 53 write_register ( IPOL, values );
antonio_actus 1:3bda347154e6 54 }
antonio_actus 1:3bda347154e6 55
antonio_actus 1:3bda347154e6 56 uint8_t MCP23008_I2C::get_input_polarity () {
antonio_actus 1:3bda347154e6 57 return read_register ( IPOL );
antonio_actus 1:3bda347154e6 58 }
antonio_actus 1:3bda347154e6 59
antonio_actus 1:3bda347154e6 60 void MCP23008_I2C::set_pullups ( uint8_t values ) {
antonio_actus 1:3bda347154e6 61 write_register ( GPPU, values );
antonio_actus 1:3bda347154e6 62 }
antonio_actus 1:3bda347154e6 63
antonio_actus 1:3bda347154e6 64 uint8_t MCP23008_I2C::get_pullups () {
antonio_actus 1:3bda347154e6 65 return read_register ( GPPU );
antonio_actus 1:3bda347154e6 66 }
antonio_actus 1:3bda347154e6 67
antonio_actus 1:3bda347154e6 68 void MCP23008_I2C::interrupt_on_changes ( uint8_t pins ) {
antonio_actus 1:3bda347154e6 69 uint8_t value = read_register ( INTCON );
antonio_actus 1:3bda347154e6 70 value &= ~pins;
antonio_actus 1:3bda347154e6 71 write_register ( INTCON, value );
antonio_actus 1:3bda347154e6 72 value = read_register ( GPINTEN );
antonio_actus 1:3bda347154e6 73 value |= pins;
antonio_actus 1:3bda347154e6 74 write_register ( GPINTEN, value );
antonio_actus 1:3bda347154e6 75 }
antonio_actus 1:3bda347154e6 76
antonio_actus 1:3bda347154e6 77 void MCP23008_I2C::disable_interrupts ( uint8_t pins ) {
antonio_actus 1:3bda347154e6 78 uint8_t value = read_register ( GPINTEN );
antonio_actus 1:3bda347154e6 79 value &= ~pins;
antonio_actus 1:3bda347154e6 80 write_register ( GPINTEN, value );
antonio_actus 1:3bda347154e6 81 }
antonio_actus 1:3bda347154e6 82
antonio_actus 1:3bda347154e6 83 void MCP23008_I2C::acknowledge_interrupt ( uint8_t &pin, uint8_t &values ) {
antonio_actus 1:3bda347154e6 84 pin = read_register ( INTF );
antonio_actus 1:3bda347154e6 85 values = read_register ( INTCAP );
antonio_actus 1:3bda347154e6 86 }
antonio_actus 1:3bda347154e6 87
antonio_actus 1:3bda347154e6 88 uint8_t MCP23008_I2C::read_register ( uint8_t reg ) {
antonio_actus 1:3bda347154e6 89 char data[] = {reg};
antonio_actus 1:3bda347154e6 90 if ( 0 != _i2c->write ( _slaveAddress, data, 1 ) )
antonio_actus 1:3bda347154e6 91 error ( "MCP23008::read_register: Missing ACK for write\n" );
antonio_actus 1:3bda347154e6 92
antonio_actus 1:3bda347154e6 93 if ( 0 != _i2c->read ( _slaveAddress, data, 1 ) )
antonio_actus 1:3bda347154e6 94 error ( "MCP23008:read_register: Missing ACK for read\n" );
antonio_actus 1:3bda347154e6 95
antonio_actus 1:3bda347154e6 96 return data[0];
antonio_actus 1:3bda347154e6 97 }
antonio_actus 1:3bda347154e6 98
antonio_actus 1:3bda347154e6 99 void MCP23008_I2C::write_register (int reg, int value) {
antonio_actus 1:3bda347154e6 100 char data[] = {reg, value};
antonio_actus 1:3bda347154e6 101
antonio_actus 1:3bda347154e6 102 _i2c->write(_slaveAddress, data, 2);
antonio_actus 1:3bda347154e6 103 }
antonio_actus 1:3bda347154e6 104
antonio_actus 1:3bda347154e6 105 void MCP23008_I2C::write_mask ( uint8_t reg, uint8_t mask, bool value ) {
antonio_actus 1:3bda347154e6 106 uint8_t val;
antonio_actus 1:3bda347154e6 107 val = read_register ( reg );
antonio_actus 1:3bda347154e6 108 if ( value )
antonio_actus 1:3bda347154e6 109 val |= mask;
antonio_actus 1:3bda347154e6 110 else
antonio_actus 1:3bda347154e6 111 val &= ~mask;
antonio_actus 1:3bda347154e6 112
antonio_actus 1:3bda347154e6 113 write_register ( reg, val );
antonio_actus 1:3bda347154e6 114 }
antonio_actus 1:3bda347154e6 115
antonio_actus 1:3bda347154e6 116 void MCP23008_I2C::reset ( ) {
antonio_actus 1:3bda347154e6 117 write_register ( IODIR, 0xFF );
antonio_actus 1:3bda347154e6 118 for ( uint8_t reg = IPOL; reg <= OLAT; reg++ )
antonio_actus 1:3bda347154e6 119 write_register ( reg, 0 );
antonio_actus 1:3bda347154e6 120 }