A library for the Microchip MCP23008 I2C 8-bit I/O expander.

Committer:
dewyatt
Date:
Fri Jun 15 03:31:48 2012 +0000
Revision:
0:4f712bd739d0

        

Who changed what in which revision?

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