Added support for banked registers

Dependents:   Component_Test_Interface FalconWing MX_Spoile_Test Simple_Power_Distribution ... more

Committer:
wim
Date:
Mon Feb 13 22:14:51 2012 +0000
Revision:
5:5696b886a895
Parent:
4:868db61f5f4e

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim 0:1a9288cc0630 1 /* MCP23017 - drive the Microchip MCP23017 16-bit Port Extender using I2C
wim 0:1a9288cc0630 2 * Copyright (c) 2010 Wim Huiskamp, Romilly Cocking (original version for SPI)
wim 0:1a9288cc0630 3 *
wim 0:1a9288cc0630 4 * Released under the MIT License: http://mbed.org/license/mit
wim 0:1a9288cc0630 5 *
wim 1:e2edbd61f4d0 6 * version 0.2 Initial Release
wim 1:e2edbd61f4d0 7 * version 0.3 Cleaned up
wim 3:72da9cd002bd 8 * version 0.4 Fixed problem with _read method
wim 4:868db61f5f4e 9 * version 0.5 Added support for 'Banked' access to registers
wim 0:1a9288cc0630 10 */
wim 0:1a9288cc0630 11
wim 0:1a9288cc0630 12 #include "mbed.h"
wim 0:1a9288cc0630 13 #include "MCP23017.h"
wim 0:1a9288cc0630 14
wim 1:e2edbd61f4d0 15 /** Create an MCP23017 object connected to the specified I2C object and using the specified deviceAddress
wim 1:e2edbd61f4d0 16 *
wim 1:e2edbd61f4d0 17 * @param I2C &i2c the I2C port to connect to
wim 3:72da9cd002bd 18 * @param char deviceAddress the address of the MCP23017
wim 1:e2edbd61f4d0 19 */
wim 0:1a9288cc0630 20 MCP23017::MCP23017(I2C &i2c, char deviceAddress) : _i2c(i2c) {
wim 0:1a9288cc0630 21 _writeOpcode = deviceAddress & 0xFE; // low order bit = 0 for write
wim 0:1a9288cc0630 22 _readOpcode = deviceAddress | 0x01; // low order bit = 1 for read
wim 0:1a9288cc0630 23 _init();
wim 0:1a9288cc0630 24 }
wim 0:1a9288cc0630 25
wim 1:e2edbd61f4d0 26 /** Read from specified MCP23017 register
wim 1:e2edbd61f4d0 27 *
wim 3:72da9cd002bd 28 * @param char address the internal registeraddress of the MCP23017
wim 1:e2edbd61f4d0 29 * @returns data from register
wim 1:e2edbd61f4d0 30 */
wim 0:1a9288cc0630 31 char MCP23017::_read(char address) {
wim 0:1a9288cc0630 32 char data[2];
wim 0:1a9288cc0630 33
wim 0:1a9288cc0630 34 data[0] = address;
wim 3:72da9cd002bd 35 _i2c.write(_writeOpcode, data, 1); // Select Register for reading
wim 3:72da9cd002bd 36 _i2c.read(_readOpcode, data, 1); // Read from selected Register
wim 0:1a9288cc0630 37
wim 3:72da9cd002bd 38 return data[0];
wim 0:1a9288cc0630 39 }
wim 0:1a9288cc0630 40
wim 0:1a9288cc0630 41
wim 1:e2edbd61f4d0 42 /** Write to specified MCP23017 register
wim 1:e2edbd61f4d0 43 *
wim 3:72da9cd002bd 44 * @param char address the internal registeraddress of the MCP23017
wim 1:e2edbd61f4d0 45 */
wim 0:1a9288cc0630 46 void MCP23017::_write(char address, char byte) {
wim 0:1a9288cc0630 47 char data[2];
wim 0:1a9288cc0630 48
wim 0:1a9288cc0630 49 data[0] = address;
wim 0:1a9288cc0630 50 data[1] = byte;
wim 0:1a9288cc0630 51 _i2c.write(_writeOpcode, data, 2); // Write data to selected Register
wim 0:1a9288cc0630 52 }
wim 0:1a9288cc0630 53
wim 0:1a9288cc0630 54
wim 1:e2edbd61f4d0 55 /** Init MCP23017
wim 1:e2edbd61f4d0 56 *
wim 1:e2edbd61f4d0 57 * @param
wim 1:e2edbd61f4d0 58 * @returns
wim 1:e2edbd61f4d0 59 */
wim 0:1a9288cc0630 60 void MCP23017::_init() {
wim 4:868db61f5f4e 61
wim 4:868db61f5f4e 62 _bankMode = NOT_BNK; // This may not be true after software reset without hardware reset !!!
wim 4:868db61f5f4e 63
wim 4:868db61f5f4e 64 _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)
wim 0:1a9288cc0630 65
wim 0:1a9288cc0630 66 }
wim 0:1a9288cc0630 67
wim 1:e2edbd61f4d0 68 /** Set I/O direction of specified MCP23017 Port
wim 1:e2edbd61f4d0 69 *
wim 1:e2edbd61f4d0 70 * @param Port Port address (Port_A or Port_B)
wim 1:e2edbd61f4d0 71 * @param char direction pin direction (0 = output, 1 = input)
wim 1:e2edbd61f4d0 72 */
wim 0:1a9288cc0630 73 void MCP23017::direction(Port port, char direction) {
wim 4:868db61f5f4e 74 _write(IODIR_AB[_bankMode][port], direction);
wim 0:1a9288cc0630 75 }
wim 0:1a9288cc0630 76
wim 1:e2edbd61f4d0 77 /** Set Pull-Up Resistors on specified MCP23017 Port
wim 1:e2edbd61f4d0 78 *
wim 1:e2edbd61f4d0 79 * @param Port Port address (Port_A or Port_B)
wim 1:e2edbd61f4d0 80 * @param char offOrOn per pin (0 = off, 1 = on)
wim 1:e2edbd61f4d0 81 */
wim 0:1a9288cc0630 82 void MCP23017::configurePullUps(Port port, char offOrOn) {
wim 4:868db61f5f4e 83
wim 4:868db61f5f4e 84 _write(GPPU_AB[_bankMode][port], offOrOn);
wim 0:1a9288cc0630 85 }
wim 0:1a9288cc0630 86
wim 4:868db61f5f4e 87 /** Configere the Banked or Non-Banked mode
wim 4:868db61f5f4e 88 *
wim 4:868db61f5f4e 89 * @param Bank bankMode
wim 4:868db61f5f4e 90 * @param char offOrOn per pin (0 = off, 1 = on)
wim 4:868db61f5f4e 91 */
wim 4:868db61f5f4e 92 void MCP23017::configureBanked(Bank bankMode) {
wim 4:868db61f5f4e 93
wim 4:868db61f5f4e 94 if (bankMode == NOT_BNK) {
wim 4:868db61f5f4e 95 // Non-Banked sequential registers (default POR)
wim 4:868db61f5f4e 96 // Hardware addressing on, , no-autoincrement, 16 bit mode (operations do toggle between A and B registers)
wim 4:868db61f5f4e 97 _write(IOCON_AB[_bankMode][PORT_A], (IOCON_BYTE_MODE | IOCON_HAEN ));
wim 4:868db61f5f4e 98 _bankMode = NOT_BNK;
wim 4:868db61f5f4e 99 }
wim 4:868db61f5f4e 100 else {
wim 4:868db61f5f4e 101 // Banked registers
wim 4:868db61f5f4e 102 // Hardware addressing on, no-autoincrement, 8 bit mode
wim 4:868db61f5f4e 103 _write(IOCON_AB[_bankMode][PORT_A], (IOCON_BANK | IOCON_BYTE_MODE | IOCON_HAEN ));
wim 4:868db61f5f4e 104 _bankMode = BNK;
wim 4:868db61f5f4e 105 }
wim 4:868db61f5f4e 106 }
wim 4:868db61f5f4e 107
wim 4:868db61f5f4e 108
wim 0:1a9288cc0630 109 void MCP23017::interruptEnable(Port port, char interruptsEnabledMask) {
wim 4:868db61f5f4e 110
wim 4:868db61f5f4e 111 _write(GPINTEN_AB[_bankMode][port], interruptsEnabledMask);
wim 4:868db61f5f4e 112
wim 0:1a9288cc0630 113 }
wim 0:1a9288cc0630 114
wim 0:1a9288cc0630 115 void MCP23017::mirrorInterrupts(bool mirror) {
wim 4:868db61f5f4e 116 char iocon = _read(IOCON_AB[_bankMode][PORT_A]);
wim 4:868db61f5f4e 117
wim 4:868db61f5f4e 118 if (mirror) {
wim 4:868db61f5f4e 119 iocon = iocon | INTERRUPT_MIRROR_BIT;
wim 4:868db61f5f4e 120 }
wim 4:868db61f5f4e 121 else {
wim 4:868db61f5f4e 122 iocon = iocon & ~INTERRUPT_MIRROR_BIT;
wim 4:868db61f5f4e 123 }
wim 4:868db61f5f4e 124
wim 4:868db61f5f4e 125 _write(IOCON_AB[_bankMode][PORT_A], iocon);
wim 0:1a9288cc0630 126
wim 0:1a9288cc0630 127 }
wim 0:1a9288cc0630 128
wim 0:1a9288cc0630 129 void MCP23017::interruptPolarity(Polarity polarity) {
wim 4:868db61f5f4e 130 char iocon = _read(IOCON_AB[_bankMode][PORT_A]);
wim 4:868db61f5f4e 131
wim 0:1a9288cc0630 132 if (polarity == ACTIVE_LOW) {
wim 0:1a9288cc0630 133 iocon = iocon & ~INTERRUPT_POLARITY_BIT;
wim 0:1a9288cc0630 134 } else {
wim 0:1a9288cc0630 135 iocon = iocon | INTERRUPT_POLARITY_BIT;
wim 0:1a9288cc0630 136 }
wim 4:868db61f5f4e 137 _write(IOCON_AB[_bankMode][PORT_A], iocon);
wim 0:1a9288cc0630 138 }
wim 0:1a9288cc0630 139
wim 0:1a9288cc0630 140 void MCP23017::defaultValue(Port port, char valuesToCompare) {
wim 4:868db61f5f4e 141
wim 4:868db61f5f4e 142 _write(DEFVAL_AB[_bankMode][port], valuesToCompare);
wim 4:868db61f5f4e 143
wim 0:1a9288cc0630 144 }
wim 0:1a9288cc0630 145
wim 0:1a9288cc0630 146 void MCP23017::interruptControl(Port port, char interruptControlBits) {
wim 4:868db61f5f4e 147
wim 4:868db61f5f4e 148 _write(INTCON_AB[_bankMode][port], interruptControlBits);
wim 4:868db61f5f4e 149
wim 0:1a9288cc0630 150 }
wim 0:1a9288cc0630 151
wim 1:e2edbd61f4d0 152 /** Write to specified MCP23017 Port
wim 1:e2edbd61f4d0 153 *
wim 1:e2edbd61f4d0 154 * @param Port Port address (Port_A or Port_B)
wim 1:e2edbd61f4d0 155 * @param char byte data to write
wim 1:e2edbd61f4d0 156 */
wim 0:1a9288cc0630 157 void MCP23017::write(Port port, char byte) {
wim 4:868db61f5f4e 158 _write(OLAT_AB[_bankMode][port], byte);
wim 0:1a9288cc0630 159 }
wim 0:1a9288cc0630 160
wim 1:e2edbd61f4d0 161 /** Read from specified MCP23017 Port
wim 1:e2edbd61f4d0 162 *
wim 1:e2edbd61f4d0 163 * @param Port Port address (Port_A or Port_B)
wim 1:e2edbd61f4d0 164 * @returns data from Port
wim 1:e2edbd61f4d0 165 */
wim 0:1a9288cc0630 166 char MCP23017::read(Port port) {
wim 4:868db61f5f4e 167 return _read(GPIO_AB[_bankMode][port]);
wim 0:1a9288cc0630 168 }
wim 0:1a9288cc0630 169