Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MCP23017.cpp
00001 /* MCP23017 - drive the Microchip MCP23017 16-bit Port Extender using I2C 00002 * Copyright (c) 2010 Wim Huiskamp, Romilly Cocking (original version for SPI) 00003 * 00004 * Released under the MIT License: http://mbed.org/license/mit 00005 * 00006 * version 0.2 Initial Release 00007 * version 0.3 Cleaned up 00008 * version 0.4 Fixed problem with _read method 00009 * version 0.5 Added support for 'Banked' access to registers 00010 */ 00011 00012 #include "mbed.h" 00013 #include "MCP23017.h" 00014 00015 /** Create an MCP23017 object connected to the specified I2C object and using the specified deviceAddress 00016 * 00017 * @param I2C &i2c the I2C port to connect to 00018 * @param char deviceAddress the address of the MCP23017 00019 */ 00020 MCP23017::MCP23017(I2C &i2c, char deviceAddress) : _i2c(i2c) { 00021 _writeOpcode = deviceAddress & 0xFE; // low order bit = 0 for write 00022 _readOpcode = deviceAddress | 0x01; // low order bit = 1 for read 00023 _init(); 00024 } 00025 00026 /** Read from specified MCP23017 register 00027 * 00028 * @param char address the internal registeraddress of the MCP23017 00029 * @returns data from register 00030 */ 00031 char MCP23017::_read(char address) { 00032 char data[2]; 00033 00034 data[0] = address; 00035 _i2c.write(_writeOpcode, data, 1); // Select Register for reading 00036 _i2c.read(_readOpcode, data, 1); // Read from selected Register 00037 00038 return data[0]; 00039 } 00040 00041 00042 /** Write to specified MCP23017 register 00043 * 00044 * @param char address the internal registeraddress of the MCP23017 00045 */ 00046 void MCP23017::_write(char address, char byte) { 00047 char data[2]; 00048 00049 data[0] = address; 00050 data[1] = byte; 00051 _i2c.write(_writeOpcode, data, 2); // Write data to selected Register 00052 } 00053 00054 00055 /** Init MCP23017 00056 * 00057 * @param 00058 * @returns 00059 */ 00060 void MCP23017::_init() { 00061 00062 _bankMode = NOT_BNK; // This may not be true after software reset without hardware reset !!! 00063 00064 _write(IOCON_AB[_bankMode][PORT_A], (IOCON_BYTE_MODE | IOCON_HAEN )); // Hardware addressing on, no-autoincrement, 16 bit mode (operations toggle between A and B registers) 00065 00066 } 00067 00068 /** Set I/O direction of specified MCP23017 Port 00069 * 00070 * @param Port Port address (Port_A or Port_B) 00071 * @param char direction pin direction (0 = output, 1 = input) 00072 */ 00073 void MCP23017::direction(Port port, char direction) { 00074 _write(IODIR_AB[_bankMode][port], direction); 00075 } 00076 00077 /** Set Pull-Up Resistors on specified MCP23017 Port 00078 * 00079 * @param Port Port address (Port_A or Port_B) 00080 * @param char offOrOn per pin (0 = off, 1 = on) 00081 */ 00082 void MCP23017::configurePullUps(Port port, char offOrOn) { 00083 00084 _write(GPPU_AB[_bankMode][port], offOrOn); 00085 } 00086 00087 /** Configere the Banked or Non-Banked mode 00088 * 00089 * @param Bank bankMode 00090 * @param char offOrOn per pin (0 = off, 1 = on) 00091 */ 00092 void MCP23017::configureBanked(Bank bankMode) { 00093 00094 if (bankMode == NOT_BNK) { 00095 // Non-Banked sequential registers (default POR) 00096 // Hardware addressing on, , no-autoincrement, 16 bit mode (operations do toggle between A and B registers) 00097 _write(IOCON_AB[_bankMode][PORT_A], (IOCON_BYTE_MODE | IOCON_HAEN )); 00098 _bankMode = NOT_BNK; 00099 } 00100 else { 00101 // Banked registers 00102 // Hardware addressing on, no-autoincrement, 8 bit mode 00103 _write(IOCON_AB[_bankMode][PORT_A], (IOCON_BANK | IOCON_BYTE_MODE | IOCON_HAEN )); 00104 _bankMode = BNK; 00105 } 00106 } 00107 00108 00109 void MCP23017::interruptEnable(Port port, char interruptsEnabledMask) { 00110 00111 _write(GPINTEN_AB[_bankMode][port], interruptsEnabledMask); 00112 00113 } 00114 00115 void MCP23017::mirrorInterrupts(bool mirror) { 00116 char iocon = _read(IOCON_AB[_bankMode][PORT_A]); 00117 00118 if (mirror) { 00119 iocon = iocon | INTERRUPT_MIRROR_BIT; 00120 } 00121 else { 00122 iocon = iocon & ~INTERRUPT_MIRROR_BIT; 00123 } 00124 00125 _write(IOCON_AB[_bankMode][PORT_A], iocon); 00126 00127 } 00128 00129 void MCP23017::interruptPolarity(Polarity polarity) { 00130 char iocon = _read(IOCON_AB[_bankMode][PORT_A]); 00131 00132 if (polarity == ACTIVE_LOW) { 00133 iocon = iocon & ~INTERRUPT_POLARITY_BIT; 00134 } else { 00135 iocon = iocon | INTERRUPT_POLARITY_BIT; 00136 } 00137 _write(IOCON_AB[_bankMode][PORT_A], iocon); 00138 } 00139 00140 void MCP23017::defaultValue(Port port, char valuesToCompare) { 00141 00142 _write(DEFVAL_AB[_bankMode][port], valuesToCompare); 00143 00144 } 00145 00146 void MCP23017::interruptControl(Port port, char interruptControlBits) { 00147 00148 _write(INTCON_AB[_bankMode][port], interruptControlBits); 00149 00150 } 00151 00152 /** Write to specified MCP23017 Port 00153 * 00154 * @param Port Port address (Port_A or Port_B) 00155 * @param char byte data to write 00156 */ 00157 void MCP23017::write(Port port, char byte) { 00158 _write(OLAT_AB[_bankMode][port], byte); 00159 } 00160 00161 /** Read from specified MCP23017 Port 00162 * 00163 * @param Port Port address (Port_A or Port_B) 00164 * @returns data from Port 00165 */ 00166 char MCP23017::read(Port port) { 00167 return _read(GPIO_AB[_bankMode][port]); 00168 } 00169 00170
Generated on Fri Jul 15 2022 07:12:37 by
1.7.2