chiark / gitweb /
wiringPi Version 2 - First commit (of v2)
[wiringPi.git] / examples / 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 <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
48 static unsigned int masks [] = { 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0x07, 0xFF } ;
49
50
51 /*
52  * bcdToD: dToBCD:
53  *      BCD decode/encode
54  *********************************************************************************
55  */
56
57 static 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
66 static 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
78 static int ramTestValues [] =
79   { 0x00, 0xFF, 0xAA, 0x55, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0xF0, 0x0F, -1 } ;
80
81 static 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
133 static 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
168 static 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
198 int 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 }