3 * Extend wiringPi with the MCP 23017 I2C GPIO expander chip
4 * Copyright (c) 2013 Gordon Henderson
5 ***********************************************************************
6 * This file is part of wiringPi:
7 * https://projects.drogon.net/raspberry-pi/wiringpi/
9 * wiringPi is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation, either version 3 of the
12 * License, or (at your option) any later version.
14 * wiringPi is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with wiringPi.
21 * If not, see <http://www.gnu.org/licenses/>.
22 ***********************************************************************
29 #include "wiringPiI2C.h"
30 #include "mcp23x0817.h"
37 *********************************************************************************
40 static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
44 pin -= node->pinBase ;
46 if (pin < 8) // Bank A
47 reg = MCP23x17_IODIRA ;
50 reg = MCP23x17_IODIRB ;
55 old = wiringPiI2CReadReg8 (node->fd, reg) ;
62 wiringPiI2CWriteReg8 (node->fd, reg, old) ;
68 *********************************************************************************
71 static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
75 pin -= node->pinBase ;
77 if (pin < 8) // Bank A
78 reg = MCP23x17_GPPUA ;
81 reg = MCP23x17_GPPUB ;
86 old = wiringPiI2CReadReg8 (node->fd, reg) ;
93 wiringPiI2CWriteReg8 (node->fd, reg, old) ;
99 *********************************************************************************
102 static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
106 pin -= node->pinBase ; // Pin now 0-15
108 bit = 1 << (pin & 7) ;
110 if (pin < 8) // Bank A
119 wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOA, old) ;
131 wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOB, old) ;
139 *********************************************************************************
142 static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
144 int mask, value, gpio ;
146 pin -= node->pinBase ;
148 if (pin < 8) // Bank A
149 gpio = MCP23x17_GPIOA ;
152 gpio = MCP23x17_GPIOB ;
157 value = wiringPiI2CReadReg8 (node->fd, gpio) ;
159 if ((value & mask) == 0)
168 * Create a new instance of an MCP23017 I2C GPIO interface. We know it
169 * has 16 pins, so all we need to know here is the I2C address and the
170 * user-defined pin base.
171 *********************************************************************************
174 int mcp23017Setup (const int pinBase, const int i2cAddress)
177 struct wiringPiNodeStruct *node ;
179 if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
182 wiringPiI2CWriteReg8 (fd, MCP23x17_IOCON, IOCON_INIT) ;
184 node = wiringPiNewNode (pinBase, 16) ;
187 node->pinMode = myPinMode ;
188 node->pullUpDnControl = myPullUpDnControl ;
189 node->digitalRead = myDigitalRead ;
190 node->digitalWrite = myDigitalWrite ;
191 node->data2 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATA) ;
192 node->data3 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATB) ;