Gordons Projects

--> Projects Top-Level GIT

OK. So the Pi v2 I have had older firmware and it wasn't quite
[wiringPi] / wiringPi / mcp23008.c
1 /*
2  * mcp23008.c:
3  *      Extend wiringPi with the MCP 23008 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 "mcp23008.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   reg  = MCP23x08_IODIR ;
45   mask = 1 << (pin - node->pinBase) ;
46   old  = wiringPiI2CReadReg8 (node->fd, reg) ;
47
48   if (mode == OUTPUT)
49     old &= (~mask) ;
50   else
51     old |=   mask ;
52
53   wiringPiI2CWriteReg8 (node->fd, reg, old) ;
54 }
55
56
57 /*
58  * myPullUpDnControl:
59  *********************************************************************************
60  */
61
62 static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
63 {
64   int mask, old, reg ;
65
66   reg  = MCP23x08_GPPU ;
67   mask = 1 << (pin - node->pinBase) ;
68
69   old  = wiringPiI2CReadReg8 (node->fd, reg) ;
70
71   if (mode == PUD_UP)
72     old |=   mask ;
73   else
74     old &= (~mask) ;
75
76   wiringPiI2CWriteReg8 (node->fd, reg, old) ;
77 }
78
79
80 /*
81  * myDigitalWrite:
82  *********************************************************************************
83  */
84
85 static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
86 {
87   int bit, old ;
88
89   bit  = 1 << ((pin - node->pinBase) & 7) ;
90
91   old = node->data2 ;
92   if (value == LOW)
93     old &= (~bit) ;
94   else
95     old |=   bit ;
96
97   wiringPiI2CWriteReg8 (node->fd, MCP23x08_GPIO, old) ;
98   node->data2 = old ;
99 }
100
101
102 /*
103  * myDigitalRead:
104  *********************************************************************************
105  */
106
107 static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
108 {
109   int mask, value ;
110
111   mask  = 1 << ((pin - node->pinBase) & 7) ;
112   value = wiringPiI2CReadReg8 (node->fd, MCP23x08_GPIO) ;
113
114   if ((value & mask) == 0)
115     return LOW ;
116   else 
117     return HIGH ;
118 }
119
120
121 /*
122  * mcp23008Setup:
123  *      Create a new instance of an MCP23008 I2C GPIO interface. We know it
124  *      has 8 pins, so all we need to know here is the I2C address and the
125  *      user-defined pin base.
126  *********************************************************************************
127  */
128
129 int mcp23008Setup (const int pinBase, const int i2cAddress)
130 {
131   int fd ;
132   struct wiringPiNodeStruct *node ;
133
134   if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
135     return fd ;
136
137   wiringPiI2CWriteReg8 (fd, MCP23x08_IOCON, IOCON_INIT) ;
138
139   node = wiringPiNewNode (pinBase, 8) ;
140
141   node->fd              = fd ;
142   node->pinMode         = myPinMode ;
143   node->pullUpDnControl = myPullUpDnControl ;
144   node->digitalRead     = myDigitalRead ;
145   node->digitalWrite    = myDigitalWrite ;
146   node->data2           = wiringPiI2CReadReg8 (fd, MCP23x08_OLAT) ;
147
148   return 0 ;
149 }