Revision 0:133b7e09bbe7, committed 2016-01-19
- Comitter:
- davidr99
- Date:
- Tue Jan 19 23:50:23 2016 +0000
- Commit message:
- MCP23016 Library
Changed in this revision
diff -r 000000000000 -r 133b7e09bbe7 MCP23016.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP23016.cpp Tue Jan 19 23:50:23 2016 +0000
@@ -0,0 +1,216 @@
+/* MCP23016 library
+ Based on MCP23017 library for arduino by David Pye <davidmpye@gmail.com>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "MCP23016.h"
+#include "mbed.h"
+
+union {
+ uint8_t value8[2];
+ uint16_t value16;
+} tmp_data;
+
+/*-----------------------------------------------------------------------------
+ *
+ */
+MCP23016::MCP23016(PinName sda, PinName scl, int i2cAddress) : _i2c(sda, scl) {
+ MCP23016_i2cAddress = I2C_BASE_ADDRESS + i2cAddress;
+ reset(); // initialise chip to power-on condition
+}
+
+/*-----------------------------------------------------------------------------
+ * reset
+ * Set configuration (IOCON) and direction(IODIR) registers to initial state
+ */
+void MCP23016::reset() {
+//
+// set direction registers to inputs
+//
+ writeRegister(IODIR0, (unsigned short)0xFFFF);
+//
+// set all other registers to zero (last of 10 registers is OLAT)
+//
+ for (int reg_addr = OLAT0 ; reg_addr <= IPOL1 ; reg_addr+=2) {
+ writeRegister(reg_addr, (unsigned short)0x0000);
+ }
+//
+// Set the shadow registers to power-on state
+//
+ shadow_IODIR = 0xFFFF;
+ shadow_GPIO = 0;
+ shadow_IPOL = 0;
+}
+
+/*-----------------------------------------------------------------------------
+ * write_bit
+ * Write a 1/0 to a single bit of the 16-bit port
+ */
+void MCP23016::write_bit(int value, int bit_number) {
+ if (value == 0) {
+ shadow_GPIO &= ~(1 << bit_number);
+ } else {
+ shadow_GPIO |= 1 << bit_number;
+ }
+ writeRegister(OLAT0, (unsigned short)shadow_GPIO);
+}
+
+/*-----------------------------------------------------------------------------
+ * Write a combination of bits to the 16-bit port
+ */
+void MCP23016::write_mask(unsigned short data, unsigned short mask) {
+ shadow_GPIO = (shadow_GPIO & ~mask) | data;
+ writeRegister(OLAT0, (unsigned short)shadow_GPIO);
+}
+
+/*-----------------------------------------------------------------------------
+ * read_bit
+ * Read a single bit from the 16-bit port
+ */
+int MCP23016::read_bit(int bit_number) {
+ shadow_GPIO = readRegister(GP0);
+ return ((shadow_GPIO >> bit_number) & 0x0001);
+}
+
+/*-----------------------------------------------------------------------------
+ * read_mask
+ */
+int MCP23016::read_mask(unsigned short mask) {
+ shadow_GPIO = readRegister(GP0);
+ return (shadow_GPIO & mask);
+}
+
+/*-----------------------------------------------------------------------------
+ * Config
+ * set direction and pull-up registers
+ */
+void MCP23016::config(unsigned short dir_config, unsigned short polarity_config) {
+ shadow_IODIR = dir_config;
+ writeRegister(IODIR0, (unsigned short)shadow_IODIR);
+ shadow_IPOL = polarity_config;
+ writeRegister(IPOL0, (unsigned short)shadow_IPOL);
+}
+
+/*-----------------------------------------------------------------------------
+ * writeRegister
+ * write a byte
+ */
+void MCP23016::writeRegister(int regAddress, unsigned char data) {
+ char buffer[2];
+
+ buffer[0] = regAddress;
+ buffer[1] = data;
+ _i2c.write(MCP23016_i2cAddress, buffer, 2);
+}
+
+/*----------------------------------------------------------------------------
+ * write Register
+ * write two bytes
+ */
+void MCP23016::writeRegister(int regAddress, unsigned short data) {
+ char buffer[3];
+
+ buffer[0] = regAddress;
+ tmp_data.value16 = data;
+ buffer[1] = tmp_data.value8[0];
+ buffer[2] = tmp_data.value8[1];
+
+ _i2c.write(MCP23016_i2cAddress, buffer, 3);
+}
+
+/*-----------------------------------------------------------------------------
+ * readRegister
+ */
+int MCP23016::readRegister(int regAddress) {
+ char buffer[2];
+
+ buffer[0] = regAddress;
+ _i2c.write(MCP23016_i2cAddress, buffer, 1);
+ _i2c.read(MCP23016_i2cAddress, buffer, 2);
+
+ return ((int)(buffer[0] + (buffer[1]<<8)));
+}
+
+/*-----------------------------------------------------------------------------
+ * pinMode
+ */
+void MCP23016::pinMode(int pin, int mode) {
+ if (mode == DIR_INPUT) {
+ shadow_IODIR |= 1 << pin;
+ } else {
+ shadow_IODIR &= ~(1 << pin);
+ }
+ writeRegister(IODIR0, (unsigned short)shadow_IODIR);
+}
+
+/*-----------------------------------------------------------------------------
+ * digitalRead
+ */
+int MCP23016::digitalRead(int pin) {
+ shadow_GPIO = readRegister(GP0);
+ if ( shadow_GPIO & (1 << pin)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ * digitalWrite
+ */
+void MCP23016::digitalWrite(int pin, int val) {
+ // This will set the OUTPUT voltage
+ //as appropriate.
+ bool isOutput = !(shadow_IODIR & 1<<pin);
+
+ if (isOutput) {
+ //This is an output pin so just write the value
+ if (val) shadow_GPIO |= 1 << pin;
+ else shadow_GPIO &= ~(1 << pin);
+ writeRegister(OLAT0, (unsigned short)shadow_GPIO);
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ * digitalWordRead
+ */
+unsigned short MCP23016::digitalWordRead() {
+ shadow_GPIO = readRegister(GP0);
+ return shadow_GPIO;
+}
+
+/*-----------------------------------------------------------------------------
+ * digitalWordWrite
+ */
+void MCP23016::digitalWordWrite(unsigned short w) {
+ shadow_GPIO = w;
+ writeRegister(OLAT0, (unsigned short)shadow_GPIO);
+}
+
+/*-----------------------------------------------------------------------------
+ * inputPolarityMask
+ */
+void MCP23016::inputPolarityMask(unsigned short mask) {
+ writeRegister(IPOL0, mask);
+}
+
+/*-----------------------------------------------------------------------------
+ * inputoutputMask
+ */
+void MCP23016::inputOutputMask(unsigned short mask) {
+ shadow_IODIR = mask;
+ writeRegister(IODIR0, (unsigned short)shadow_IODIR);
+}
+
diff -r 000000000000 -r 133b7e09bbe7 MCP23016.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP23016.h Tue Jan 19 23:50:23 2016 +0000
@@ -0,0 +1,136 @@
+/* MCP23016 library
+ Based on MCP23017 library for arduino by David Pye <davidmpye@gmail.com>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef MBED_MCP23016_H
+#define MBED_MCP23016_H
+
+#include "mbed.h"
+
+#define GP0 0x00 // Access to GP0
+#define GP1 0x01 // Access to GP1
+#define OLAT0 0x02 // Access to OLAT0
+#define OLAT1 0x03 // Access to OLAT1
+#define IPOL0 0x04 // Access to IPOL0
+#define IPOL1 0x05 // Access to IPOL1
+#define IODIR0 0x06 // Access to IODIR0
+#define IODIR1 0x07 // Access to IODIR1
+#define INTCAP0 0x08 // Access to INTCAP0 (Read-Only)
+#define INTCAP1 0x09 // Access to INTCAP1 (Read-Only)
+#define IOCON0 0x0A // Access to IOCON0
+#define IOCON1 0x0B // Access to IOCON1
+
+#define I2C_BASE_ADDRESS 0x40
+
+#define DIR_OUTPUT 0
+#define DIR_INPUT 1
+
+/** MCP23016 class
+ *
+ * Allow access to an I2C connected MCP23016 16-bit I/O extender chip
+ * Example:
+ * @code
+ * MCP23016 *par_port;
+ * @endcode
+ *
+ */
+class MCP23016 {
+public:
+ /** Constructor for the MCP23016 connected to specified I2C pins at a specific address
+ *
+ * 16-bit I/O expander with I2C interface
+ *
+ * @param sda I2C data pin
+ * @param scl I2C clock pin
+ * @param i2cAddress I2C address
+ */
+ MCP23016(PinName sda, PinName scl, int i2cAddress);
+
+ /** Reset MCP23016 device to its power-on state
+ */
+ void reset(void);
+
+ /** Write a 0/1 value to an output bit
+ *
+ * @param value 0 or 1
+ * @param bit_number bit number range 0 --> 15
+ */
+ void write_bit(int value, int bit_number);
+
+ /** Write a masked 16-bit value to the device
+ *
+ * @param data 16-bit data value
+ * @param mask 16-bit mask value
+ */
+ void write_mask(unsigned short data, unsigned short mask);
+
+ /** Read a 0/1 value from an input bit
+ *
+ * @param bit_number bit number range 0 --> 15
+ * @return 0/1 value read
+ */
+ int read_bit(int bit_number);
+
+ /** Read a 16-bit value from the device and apply mask
+ *
+ * @param mask 16-bit mask value
+ * @return 16-bit data with mask applied
+ */
+ int read_mask(unsigned short mask);
+
+ /** Configure an MCP23016 device
+ *
+ * @param dir_config data direction value (1 = input, 0 = output)
+ * @param polarity_config polarity value (1 = flip, 0 = normal)
+ */
+ void config(unsigned short dir_config, unsigned short polarity_config);
+
+ void writeRegister(int regAddress, unsigned char val);
+ void writeRegister(int regAddress, unsigned short val);
+ int readRegister(int regAddress);
+
+/*-----------------------------------------------------------------------------
+ * pinmode
+ * Set units to sequential, bank0 mode
+ */
+ void pinMode(int pin, int mode);
+ void digitalWrite(int pin, int val);
+ int digitalRead(int pin);
+
+// These provide a more advanced mapping of the chip functionality
+// See the data sheet for more information on what they do
+
+//Returns a word with the current pin states (ie contents of the GPIO register)
+ unsigned short digitalWordRead();
+// Allows you to write a word to the GPIO register
+ void digitalWordWrite(unsigned short w);
+// Sets up the polarity mask that the MCP23016 supports
+// if set to 1, it will flip the actual pin value.
+ void inputPolarityMask(unsigned short mask);
+//Sets which pins are inputs or outputs (1 = input, 0 = output) NB Opposite to arduino's
+//definition for these
+ void inputOutputMask(unsigned short mask);
+ int read(void);
+ void write(int data);
+
+protected:
+ I2C _i2c;
+ int MCP23016_i2cAddress; // physical I2C address
+ unsigned short shadow_GPIO, shadow_IODIR, shadow_IPOL; // Cached copies of the register values
+
+};
+
+#endif
\ No newline at end of file