Gordons Projects

--> Projects Top-Level GIT

Many changes - tidying up the extensions interfaces.
[wiringPi] / wiringPi / sr595.c
1 /*
2  * sr595.c:
3  *      Extend wiringPi with the 74x595 shift register as a GPIO
4  *      expander chip.
5  *      Note that the code can cope with a number of 595's
6  *      daisy-chained together - up to 4 for now as we're storing
7  *      the output "register" in a single unsigned int.
8  *
9  *      Copyright (c) 2013 Gordon Henderson
10  ***********************************************************************
11  * This file is part of wiringPi:
12  *      https://projects.drogon.net/raspberry-pi/wiringpi/
13  *
14  *    wiringPi is free software: you can redistribute it and/or modify
15  *    it under the terms of the GNU Lesser General Public License as
16  *    published by the Free Software Foundation, either version 3 of the
17  *    License, or (at your option) any later version.
18  *
19  *    wiringPi is distributed in the hope that it will be useful,
20  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *    GNU Lesser General Public License for more details.
23  *
24  *    You should have received a copy of the GNU Lesser General Public
25  *    License along with wiringPi.
26  *    If not, see <http://www.gnu.org/licenses/>.
27  ***********************************************************************
28  */
29
30 #include <stdio.h>
31 #include <stdint.h>
32
33 #include "wiringPi.h"
34
35 #include "sr595.h"
36
37
38 /*
39  * myDigitalWrite:
40  *********************************************************************************
41  */
42
43 static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
44 {
45   unsigned int mask ;
46   int  dataPin, clockPin, latchPin ;
47   int  bit, bits, output ;
48
49   pin     -= node->pinBase ;                            // Normalise pin number
50   bits     = node->pinMax - node->pinBase + 1 ;         // ie. number of clock pulses
51   dataPin  = node->data0 ;
52   clockPin = node->data1 ;
53   latchPin = node->data2 ;
54   output   = node->data3 ;
55
56   mask = 1 << pin ;
57
58   if (value == LOW)
59     output &= (~mask) ;
60   else
61     output |=   mask ;
62
63   node->data3 = output ;
64
65 // A low -> high latch transition copies the latch to the output pins
66
67   digitalWrite (latchPin, LOW) ; delayMicroseconds (1) ;
68     for (bit = bits - 1 ; bit >= 0 ; --bit)
69     {
70       digitalWrite (dataPin, output & (1 << bit)) ;
71
72       digitalWrite (clockPin, HIGH) ; delayMicroseconds (1) ;
73       digitalWrite (clockPin, LOW) ;  delayMicroseconds (1) ;
74     }
75   digitalWrite (latchPin, HIGH) ; delayMicroseconds (1) ;
76 }
77
78
79 /*
80  * sr595Setup:
81  *      Create a new instance of a 74x595 shift register GPIO expander.
82  *********************************************************************************
83  */
84
85 int sr595Setup (const int pinBase, const int numPins,
86         const int dataPin, const int clockPin, const int latchPin) 
87 {
88   struct wiringPiNodeStruct *node ;
89
90   node = wiringPiNewNode (pinBase, numPins) ;
91
92   node->data0           = dataPin ;
93   node->data1           = clockPin ;
94   node->data2           = latchPin ;
95   node->data3           = 0 ;           // Output register
96   node->digitalWrite    = myDigitalWrite ;
97
98 // Initialise the underlying hardware
99
100   digitalWrite (dataPin,  LOW) ;
101   digitalWrite (clockPin, LOW) ;
102   digitalWrite (latchPin, HIGH) ;
103
104   pinMode (dataPin,  OUTPUT) ;
105   pinMode (clockPin, OUTPUT) ;
106   pinMode (latchPin, OUTPUT) ;
107
108   return TRUE ;
109 }