Gordons Projects

--> Projects Top-Level GIT

Updated wiringPi for the new Pi Zero.
[wiringPi] / devLib / ds1302.c
1 /*
2  * ds1302.c:
3  *      Real Time clock
4  *
5  * Copyright (c) 2013 Gordon Henderson.
6  ***********************************************************************
7  * This file is part of wiringPi:
8  *      https://projects.drogon.net/raspberry-pi/wiringpi/
9  *
10  *    wiringPi is free software: you can redistribute it and/or modify
11  *    it under the terms of the GNU Lesser General Public License as published by
12  *    the Free Software Foundation, either version 3 of the License, or
13  *    (at your option) any later version.
14  *
15  *    wiringPi is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU Lesser General Public License for more details.
19  *
20  *    You should have received a copy of the GNU Lesser General Public License
21  *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
22  ***********************************************************************
23  */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stdint.h>
28 #include <stdarg.h>
29
30 #include <wiringPi.h>
31
32 #include "ds1302.h"
33
34 // Register defines
35
36 #define RTC_SECS         0
37 #define RTC_MINS         1
38 #define RTC_HOURS        2
39 #define RTC_DATE         3
40 #define RTC_MONTH        4
41 #define RTC_DAY          5
42 #define RTC_YEAR         6
43 #define RTC_WP           7
44 #define RTC_TC           8
45 #define RTC_BM          31
46
47
48 // Locals
49
50 static int dPin, cPin, sPin ;
51
52 /*
53  * dsShiftIn:
54  *      Shift a number in from the chip, LSB first. Note that the data is
55  *      sampled on the trailing edge of the last clock, so it's valid immediately.
56  *********************************************************************************
57  */
58
59 static unsigned int dsShiftIn (void)
60 {
61   uint8_t value = 0 ;
62   int i ;
63
64   pinMode (dPin, INPUT) ;       delayMicroseconds (1) ;
65
66   for (i = 0 ; i < 8 ; ++i)
67   {
68     value |= (digitalRead (dPin) << i) ;
69     digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ;
70     digitalWrite (cPin, LOW) ;  delayMicroseconds (1) ;
71   }
72
73   return value;
74 }
75
76
77 /*
78  * dsShiftOut:
79  *      A normal LSB-first shift-out, just slowed down a bit - the Pi is
80  *      a bit faster than the chip can handle.
81  *********************************************************************************
82  */
83
84 static void dsShiftOut (unsigned int data)
85 {
86   int i ;
87
88   pinMode (dPin, OUTPUT) ;
89
90   for (i = 0 ; i < 8 ; ++i)
91   {
92     digitalWrite (dPin, data & (1 << i)) ;      delayMicroseconds (1) ;
93     digitalWrite (cPin, HIGH) ;                 delayMicroseconds (1) ;
94     digitalWrite (cPin, LOW) ;                  delayMicroseconds (1) ;
95   }
96 }
97
98
99 /*
100  * ds1302regRead: ds1302regWrite:
101  *      Read/Write a value to an RTC Register or RAM location on the chip
102  *********************************************************************************
103  */
104
105 static unsigned int ds1302regRead (const int reg)
106 {
107   unsigned int data ;
108
109   digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
110     dsShiftOut (reg) ;
111     data = dsShiftIn () ;
112   digitalWrite (sPin, LOW)  ; delayMicroseconds (1) ;
113
114   return data ;
115 }
116
117 static void ds1302regWrite (const int reg, const unsigned int data)
118 {
119   digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
120     dsShiftOut (reg) ;
121     dsShiftOut (data) ;
122   digitalWrite (sPin, LOW)  ; delayMicroseconds (1) ;
123 }
124
125
126 /*
127  * ds1302rtcWrite: ds1302rtcRead:
128  *      Writes/Reads the data to/from the RTC register
129  *********************************************************************************
130  */
131
132 unsigned int ds1302rtcRead (const int reg)
133 {
134   return ds1302regRead (0x81 | ((reg & 0x1F) << 1)) ;
135 }
136
137 void ds1302rtcWrite (int reg, unsigned int data)
138 {
139   ds1302regWrite (0x80 | ((reg & 0x1F) << 1), data) ;
140 }
141
142
143 /*
144  * ds1302ramWrite: ds1302ramRead:
145  *      Writes/Reads the data to/from the RTC register
146  *********************************************************************************
147  */
148
149 unsigned int ds1302ramRead (const int addr)
150 {
151   return ds1302regRead (0xC1 | ((addr & 0x1F) << 1)) ;
152 }
153
154 void ds1302ramWrite (const int addr, const unsigned int data)
155 {
156   ds1302regWrite ( 0xC0 | ((addr & 0x1F) << 1), data) ;
157 }
158
159 /*
160  * ds1302clockRead:
161  *      Read all 8 bytes of the clock in a single operation
162  *********************************************************************************
163  */
164
165 void ds1302clockRead (int clockData [8])
166 {
167   int i ;
168   unsigned int regVal = 0x81 | ((RTC_BM & 0x1F) << 1) ;
169
170   digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
171
172   dsShiftOut (regVal) ;
173   for (i = 0 ; i < 8 ; ++i)
174     clockData [i] = dsShiftIn () ;
175
176   digitalWrite (sPin, LOW) ;  delayMicroseconds (1) ;
177 }
178
179
180 /*
181  * ds1302clockWrite:
182  *      Write all 8 bytes of the clock in a single operation
183  *********************************************************************************
184  */
185
186 void ds1302clockWrite (const int clockData [8])
187 {
188   int i ;
189   unsigned int regVal = 0x80 | ((RTC_BM & 0x1F) << 1) ;
190
191   digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
192
193   dsShiftOut (regVal) ;
194   for (i = 0 ; i < 8 ; ++i)
195     dsShiftOut (clockData [i]) ;
196
197   digitalWrite (sPin, LOW) ;  delayMicroseconds (1) ;
198 }
199
200
201 /*
202  * ds1302trickleCharge:
203  *      Set the bits on the trickle charger.
204  *      Probably best left alone...
205  *********************************************************************************
206  */
207
208 void ds1302trickleCharge (const int diodes, const int resistors)
209 {
210   if (diodes + resistors == 0)
211     ds1302rtcWrite (RTC_TC, 0x5C) ;     // Disabled
212   else
213     ds1302rtcWrite (RTC_TC, 0xA0 | ((diodes & 3) << 2) | (resistors & 3)) ;
214 }
215
216
217
218
219 /*
220  * ds1302setup:
221  *      Initialise the chip & remember the pins we're using
222  *********************************************************************************
223  */
224
225 void ds1302setup (const int clockPin, const int dataPin, const int csPin)
226 {
227   dPin = dataPin ;
228   cPin = clockPin ;
229   sPin = csPin ;
230
231   digitalWrite (dPin, LOW) ;
232   digitalWrite (cPin, LOW) ;
233   digitalWrite (sPin, LOW) ;
234
235   pinMode (dPin, OUTPUT) ;
236   pinMode (cPin, OUTPUT) ;
237   pinMode (sPin, OUTPUT) ;
238
239   ds1302rtcWrite (RTC_WP, 0) ;  // Remove write-protect
240 }