chiark / gitweb /
Debian build: Fix .so symlinks
[wiringPi.git] / wiringPi / pcf8574.c
1 /*
2  * pcf8574.c:
3  *      Extend wiringPi with the PCF8574 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
31 #include "pcf8574.h"
32
33
34 /*
35  * myPinMode:
36  *      The PCF8574 is an odd chip - the pins are effectively bi-directional,
37  *      however the pins should be drven high when used as an input pin...
38  *      So, we're effectively copying digitalWrite...
39  *********************************************************************************
40  */
41
42 static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
43 {
44   int bit, old ;
45
46   bit  = 1 << ((pin - node->pinBase) & 7) ;
47
48   old = node->data2 ;
49   if (mode == OUTPUT)
50     old &= (~bit) ;     // Write bit to 0
51   else
52     old |=   bit ;      // Write bit to 1
53
54   wiringPiI2CWrite (node->fd, old) ;
55   node->data2 = old ;
56 }
57
58
59
60 /*
61  * myDigitalWrite:
62  *********************************************************************************
63  */
64
65 static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
66 {
67   int bit, old ;
68
69   bit  = 1 << ((pin - node->pinBase) & 7) ;
70
71   old = node->data2 ;
72   if (value == LOW)
73     old &= (~bit) ;
74   else
75     old |=   bit ;
76
77   wiringPiI2CWrite (node->fd, old) ;
78   node->data2 = old ;
79 }
80
81
82 /*
83  * myDigitalRead:
84  *********************************************************************************
85  */
86
87 static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
88 {
89   int mask, value ;
90
91   mask  = 1 << ((pin - node->pinBase) & 7) ;
92   value = wiringPiI2CRead (node->fd) ;
93
94   if ((value & mask) == 0)
95     return LOW ;
96   else 
97     return HIGH ;
98 }
99
100
101 /*
102  * pcf8574Setup:
103  *      Create a new instance of a PCF8574 I2C GPIO interface. We know it
104  *      has 8 pins, so all we need to know here is the I2C address and the
105  *      user-defined pin base.
106  *********************************************************************************
107  */
108
109 int pcf8574Setup (const int pinBase, const int i2cAddress)
110 {
111   int fd ;
112   struct wiringPiNodeStruct *node ;
113
114   if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
115     return fd ;
116
117   node = wiringPiNewNode (pinBase, 8) ;
118
119   node->fd           = fd ;
120   node->pinMode      = myPinMode ;
121   node->digitalRead  = myDigitalRead ;
122   node->digitalWrite = myDigitalWrite ;
123   node->data2        = wiringPiI2CRead (fd) ;
124
125   return 0 ;
126 }