Jasmine Karlsson
/
train_rail
New project
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Fri Jul 22 2022 17:31:31 by 1.7.2