blob: f1e9e205724df1f863319ef340bd1a513aa01fd1 [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 <string.h>
29#include <time.h>
30
31#include <wiringPi.h>
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
48static unsigned int masks [] = { 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0x07, 0xFF } ;
49
50
51/*
52 * bcdToD: dToBCD:
53 * BCD decode/encode
54 *********************************************************************************
55 */
56
57static int bcdToD (unsigned int byte, unsigned int mask)
58{
59 unsigned int b1, b2 ;
60 byte &= mask ;
61 b1 = byte & 0x0F ;
62 b2 = ((byte >> 4) & 0x0F) * 10 ;
63 return b1 + b2 ;
64}
65
66static unsigned int dToBcd (unsigned int byte)
67{
68 return ((byte / 10) << 4) + (byte % 10) ;
69}
70
71
72/*
73 * ramTest:
74 * Simple test of the 31 bytes of RAM inside the DS1302 chip
75 *********************************************************************************
76 */
77
78static int ramTestValues [] =
79 { 0x00, 0xFF, 0xAA, 0x55, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0xF0, 0x0F, -1 } ;
80
81static int ramTest (void)
82{
83 int addr ;
84 int got ;
85 int i = 0 ;
86 int errors = 0 ;
87 int testVal ;
88
89 printf ("DS1302 RAM TEST\n") ;
90
91 testVal = ramTestValues [i] ;
92
93 while (testVal != -1)
94 {
95 for (addr = 0 ; addr < 31 ; ++addr)
96 ds1302ramWrite (addr, testVal) ;
97
98 for (addr = 0 ; addr < 31 ; ++addr)
99 if ((got = ds1302ramRead (addr)) != testVal)
100 {
101 printf ("DS1302 RAM Failure: Address: %2d, Expected: 0x%02X, Got: 0x%02X\n",
102 addr, testVal, got) ;
103 ++errors ;
104 }
105 testVal = ramTestValues [++i] ;
106 }
107
108 for (addr = 0 ; addr < 31 ; ++addr)
109 ds1302ramWrite (addr, addr) ;
110
111 for (addr = 0 ; addr < 31 ; ++addr)
112 if ((got = ds1302ramRead (addr)) != addr)
113 {
114 printf ("DS1302 RAM Failure: Address: %2d, Expected: 0x%02X, Got: 0x%02X\n",
115 addr, addr, got) ;
116 ++errors ;
117 }
118
119 if (errors == 0)
120 printf ("-- DS1302 RAM TEST: OK\n") ;
121 else
122 printf ("-- DS1302 RAM TEST FAILURE. %d errors.\n", errors) ;
123
124 return 0 ;
125}
126
127/*
128 * setLinuxClock:
129 * Set the Linux clock from the hardware
130 *********************************************************************************
131 */
132
133static int setLinuxClock (void)
134{
135 char dateTime [20] ;
136 char command [64] ;
137 int clock [8] ;
138
139
140 printf ("Setting the Linux Clock from the DS1302... ") ; fflush (stdout) ;
141
142 ds1302clockRead (clock) ;
143
144// [MMDDhhmm[[CC]YY][.ss]]
145
146 sprintf (dateTime, "%02d%02d%02d%02d%02d%02d.%02d",
147 bcdToD (clock [RTC_MONTH], masks [RTC_MONTH]),
148 bcdToD (clock [RTC_DATE], masks [RTC_DATE]),
149 bcdToD (clock [RTC_HOURS], masks [RTC_HOURS]),
150 bcdToD (clock [RTC_MINS], masks [RTC_MINS]),
151 20,
152 bcdToD (clock [RTC_YEAR], masks [RTC_YEAR]),
153 bcdToD (clock [RTC_SECS], masks [RTC_SECS])) ;
154
155 sprintf (command, "/bin/date %s", dateTime) ;
156 system (command) ;
157
158 return 0 ;
159}
160
161
162/*
163 * setDSclock:
164 * Set the DS1302 block from Linux time
165 *********************************************************************************
166 */
167
168static int setDSclock (void)
169{
170 struct tm t ;
171 time_t now ;
172 int clock [8] ;
173
174 printf ("Setting the clock in the DS1302 from Linux time... ") ;
175
176 now = time (NULL) ;
177 gmtime_r (&now, &t) ;
178
179 clock [ 0] = dToBcd (t.tm_sec) ; // seconds
180 clock [ 1] = dToBcd (t.tm_min) ; // mins
181 clock [ 2] = dToBcd (t.tm_hour) ; // hours
182 clock [ 3] = dToBcd (t.tm_mday) ; // date
183 clock [ 4] = dToBcd (t.tm_mon + 1) ; // months 0-11 --> 1-12
184 clock [ 5] = dToBcd (t.tm_wday + 1) ; // weekdays (sun 0)
185 clock [ 6] = dToBcd (t.tm_year - 100) ; // years
186 clock [ 7] = 0 ; // W-Protect off
187
188 ds1302clockWrite (clock) ;
189
190 printf ("OK\n") ;
191
192 return 0 ;
193}
194
195
196
197
198int main (int argc, char *argv [])
199{
200 int i ;
201 int clock [8] ;
202
203 wiringPiSetup () ;
204 ds1302setup (0, 1, 2) ;
205
206 if (argc == 2)
207 {
208 /**/ if (strcmp (argv [1], "-slc") == 0)
209 return setLinuxClock () ;
210 else if (strcmp (argv [1], "-sdsc") == 0)
211 return setDSclock () ;
212 else if (strcmp (argv [1], "-rtest") == 0)
213 return ramTest () ;
214 else
215 {
216 printf ("Usage: ds1302 [-slc | -sdsc | -rtest]\n") ;
217 return EXIT_FAILURE ;
218 }
219 }
220
221 for (i = 0 ;; ++i)
222 {
223 printf ("%5d: ", i) ;
224
225 ds1302clockRead (clock) ;
226 printf (" %2d:%02d:%02d",
227 bcdToD (clock [2], masks [2]), bcdToD (clock [1], masks [1]), bcdToD (clock [0], masks [0])) ;
228
229 printf (" %2d/%02d/%04d",
230 bcdToD (clock [3], masks [3]), bcdToD (clock [4], masks [4]), bcdToD (clock [6], masks [6]) + 2000) ;
231
232 printf ("\n") ;
233
234 delay (200) ;
235 }
236
237 return 0 ;
238}