version for testing not implemented: delta loop safety, power surge, calibration mode

Dependencies:   mbed TextLCD

Committer:
KoenKahlman
Date:
Thu Jun 27 09:26:40 2019 +0000
Revision:
3:7cfbf73d6809
Parent:
0:9c82986d7cb9
ignores power surge on startup

Who changed what in which revision?

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