blob: cf64de77d7a7607bf271df680253291976af6ec0 [file] [log] [blame]
Deokgyu Yang2c7e86b2020-04-28 10:56:11 +09001/*
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
50static 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
59static 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
84static 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
105static 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
117static 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
132unsigned int ds1302rtcRead (const int reg)
133{
134 return ds1302regRead (0x81 | ((reg & 0x1F) << 1)) ;
135}
136
137void 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
149unsigned int ds1302ramRead (const int addr)
150{
151 return ds1302regRead (0xC1 | ((addr & 0x1F) << 1)) ;
152}
153
154void 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
165void 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
186void 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
208void 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
225void 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}