Gordons Projects

--> Projects Top-Level GIT

OK. So the Pi v2 I have had older firmware and it wasn't quite
[wiringPi] / wiringPi / mcp23017.c
1 /*
2  * mcp23017.c:
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/
8  *
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.
13  *
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.
18  *
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  ***********************************************************************
23  */
24
25 #include <stdio.h>
26 #include <pthread.h>
27
28 #include "wiringPi.h"
29 #include "wiringPiI2C.h"
30 #include "mcp23x0817.h"
31
32 #include "mcp23017.h"
33
34
35 /*
36  * myPinMode:
37  *********************************************************************************
38  */
39
40 static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
41 {
42   int mask, old, reg ;
43
44   pin -= node->pinBase ;
45
46   if (pin < 8)          // Bank A
47     reg  = MCP23x17_IODIRA ;
48   else
49   {
50     reg  = MCP23x17_IODIRB ;
51     pin &= 0x07 ;
52   }
53
54   mask = 1 << pin ;
55   old  = wiringPiI2CReadReg8 (node->fd, reg) ;
56
57   if (mode == OUTPUT)
58     old &= (~mask) ;
59   else
60     old |=   mask ;
61
62   wiringPiI2CWriteReg8 (node->fd, reg, old) ;
63 }
64
65
66 /*
67  * myPullUpDnControl:
68  *********************************************************************************
69  */
70
71 static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
72 {
73   int mask, old, reg ;
74
75   pin -= node->pinBase ;
76
77   if (pin < 8)          // Bank A
78     reg  = MCP23x17_GPPUA ;
79   else
80   {
81     reg  = MCP23x17_GPPUB ;
82     pin &= 0x07 ;
83   }
84
85   mask = 1 << pin ;
86   old  = wiringPiI2CReadReg8 (node->fd, reg) ;
87
88   if (mode == PUD_UP)
89     old |=   mask ;
90   else
91     old &= (~mask) ;
92
93   wiringPiI2CWriteReg8 (node->fd, reg, old) ;
94 }
95
96
97 /*
98  * myDigitalWrite:
99  *********************************************************************************
100  */
101
102 static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
103 {
104   int bit, old ;
105
106   pin -= node->pinBase ;        // Pin now 0-15
107
108   bit = 1 << (pin & 7) ;
109
110   if (pin < 8)                  // Bank A
111   {
112     old = node->data2 ;
113
114     if (value == LOW)
115       old &= (~bit) ;
116     else
117       old |=   bit ;
118
119     wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOA, old) ;
120     node->data2 = old ;
121   }
122   else                          // Bank B
123   {
124     old = node->data3 ;
125
126     if (value == LOW)
127       old &= (~bit) ;
128     else
129       old |=   bit ;
130
131     wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOB, old) ;
132     node->data3 = old ;
133   }
134 }
135
136
137 /*
138  * myDigitalRead:
139  *********************************************************************************
140  */
141
142 static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
143 {
144   int mask, value, gpio ;
145
146   pin -= node->pinBase ;
147
148   if (pin < 8)          // Bank A
149     gpio  = MCP23x17_GPIOA ;
150   else
151   {
152     gpio  = MCP23x17_GPIOB ;
153     pin  &= 0x07 ;
154   }
155
156   mask  = 1 << pin ;
157   value = wiringPiI2CReadReg8 (node->fd, gpio) ;
158
159   if ((value & mask) == 0)
160     return LOW ;
161   else 
162     return HIGH ;
163 }
164
165
166 /*
167  * mcp23017Setup:
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  *********************************************************************************
172  */
173
174 int mcp23017Setup (const int pinBase, const int i2cAddress)
175 {
176   int fd ;
177   struct wiringPiNodeStruct *node ;
178
179   if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
180     return fd ;
181
182   wiringPiI2CWriteReg8 (fd, MCP23x17_IOCON, IOCON_INIT) ;
183
184   node = wiringPiNewNode (pinBase, 16) ;
185
186   node->fd              = fd ;
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) ;
193
194   return 0 ;
195 }