2 * ds1302.c - Support for the Dallas Semiconductor DS1302 Timekeeping Chip
4 * Rex G. Feany <rfeany@zumanetworks.com>
12 #if defined(CONFIG_RTC_DS1302) && (CONFIG_COMMANDS & CFG_CMD_DATE)
19 /* Happy Fun Defines(tm) */
20 #define RESET rtc_go_low(RST), rtc_go_low(SCLK)
21 #define N_RESET rtc_go_high(RST), rtc_go_low(SCLK)
23 #define CLOCK_HIGH rtc_go_high(SCLK)
24 #define CLOCK_LOW rtc_go_low(SCLK)
26 #define DATA_HIGH rtc_go_high(DATA)
27 #define DATA_LOW rtc_go_low(DATA)
28 #define DATA_READ (GTREGREAD(GPP_VALUE) & DATA)
33 # define DPRINTF(x,args...) printf("ds1302: " x , ##args)
34 static inline void DUMP(const char *ptr
, int num
)
36 while (num
--) printf("%x ", *ptr
++);
40 # define DPRINTF(x,args...)
41 # define DUMP(ptr, num)
44 /* time data format for DS1302 */
47 unsigned char CH
:1; /* clock halt 1=stop 0=start */
48 unsigned char sec10
:3;
51 unsigned char zero0
:1;
52 unsigned char min10
:3;
55 unsigned char fmt
:1; /* 1=12 hour 0=24 hour */
56 unsigned char zero1
:1;
57 unsigned char hr10
:2; /* 10 (0-2) or am/pm (am/pm, 0-1) */
60 unsigned char zero2
:2;
61 unsigned char date10
:2;
64 unsigned char zero3
:3;
65 unsigned char month10
:1;
66 unsigned char month
:4;
68 unsigned char zero4
:5;
69 unsigned char day
:3; /* day of week */
71 unsigned char year10
:4;
74 unsigned char WP
:1; /* write protect 1=protect 0=unprot */
75 unsigned char zero5
:7;
78 static int ds1302_initted
=0;
82 rtc_go_high(unsigned int mask
)
84 unsigned int f
= GTREGREAD(GPP_VALUE
) | mask
;
86 GT_REG_WRITE(GPP_VALUE
, f
);
90 rtc_go_low(unsigned int mask
)
92 unsigned int f
= GTREGREAD(GPP_VALUE
) & ~mask
;
94 GT_REG_WRITE(GPP_VALUE
, f
);
98 rtc_go_input(unsigned int mask
)
100 unsigned int f
= GTREGREAD(GPP_IO_CONTROL
) & ~mask
;
102 GT_REG_WRITE(GPP_IO_CONTROL
, f
);
106 rtc_go_output(unsigned int mask
)
108 unsigned int f
= GTREGREAD(GPP_IO_CONTROL
) | mask
;
110 GT_REG_WRITE(GPP_IO_CONTROL
, f
);
113 /* Access data in RTC */
116 write_byte(unsigned char b
)
119 unsigned char mask
=1;
122 CLOCK_LOW
; /* Lower clock */
123 (b
&mask
)?DATA_HIGH
:DATA_LOW
; /* set data */
125 CLOCK_HIGH
; /* latch data with rising clock */
135 unsigned char mask
=1;
141 if (DATA_READ
) b
|=mask
; /* if this bit is high, set in b */
142 CLOCK_HIGH
; /* clock out next bit */
150 read_ser_drv(unsigned char addr
, unsigned char *buf
, int count
)
157 DPRINTF("READ 0x%x bytes @ 0x%x [ ", count
, addr
);
163 rtc_go_input(DATA
); /* Put gpp pin into input mode */
165 for(i
=0;i
<count
;i
++) *(buf
++)=read_byte();
167 rtc_go_output(DATA
);/* Reset gpp for output */
174 write_ser_drv(unsigned char addr
, unsigned char *buf
, int count
)
178 DPRINTF("WRITE 0x%x bytes @ 0x%x [ ", count
, addr
);
181 addr
&=~1; /* WRITE */
185 for(i
=0;i
<count
;i
++) write_byte(*(buf
++));
194 struct ds1302_st bbclk
;
200 rtc_go_output(DATA
|SCLK
|RST
);
202 /* disable write protect */
204 write_ser_drv(0x8e,&b
,1);
207 b
= 0xa5; /* 1010.0101 */
208 write_ser_drv(0x90,&b
,1);
211 read_ser_drv(0xbe, (unsigned char *)&bbclk
, 8);
216 printf("ds1302: Clock was halted, starting clock\n");
222 printf("ds1302: Clock was in 12 hour mode, fixing\n");
228 printf("ds1302: Year was corrupted, fixing\n");
229 bbclk
.year10
=100/10; /* 2000 - why not? ;) */
234 /* Write out the changes if needed */
236 /* enable write protect */
238 write_ser_drv(0xbe,(unsigned char *)&bbclk
,8);
240 /* Else just turn write protect on */
242 write_ser_drv(0x8e,&b
,1);
244 DPRINTF("init done\n");
252 if(!ds1302_initted
) rtc_init();
257 rtc_get(struct rtc_time
*tmp
)
259 struct ds1302_st bbclk
;
261 if(!ds1302_initted
) rtc_init();
263 read_ser_drv(0xbe,(unsigned char *)&bbclk
, 8); /* read burst */
266 printf("ds1302: rtc_get: Clock was halted, clock probably "
270 tmp
->tm_sec
=10*bbclk
.sec10
+bbclk
.sec
;
271 tmp
->tm_min
=10*bbclk
.min10
+bbclk
.min
;
272 tmp
->tm_hour
=10*bbclk
.hr10
+bbclk
.hr
;
273 tmp
->tm_wday
=bbclk
.day
;
274 tmp
->tm_mday
=10*bbclk
.date10
+bbclk
.date
;
275 tmp
->tm_mon
=10*bbclk
.month10
+bbclk
.month
;
276 tmp
->tm_year
=10*bbclk
.year10
+bbclk
.year
+ 1900;
281 DPRINTF("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
282 tmp
->tm_year
, tmp
->tm_mon
, tmp
->tm_mday
, tmp
->tm_wday
,
283 tmp
->tm_hour
, tmp
->tm_min
, tmp
->tm_sec
);
287 rtc_set(struct rtc_time
*tmp
)
289 struct ds1302_st bbclk
;
292 if(!ds1302_initted
) rtc_init();
294 DPRINTF("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
295 tmp
->tm_year
, tmp
->tm_mon
, tmp
->tm_mday
, tmp
->tm_wday
,
296 tmp
->tm_hour
, tmp
->tm_min
, tmp
->tm_sec
);
298 memset(&bbclk
,0,sizeof(bbclk
));
299 bbclk
.CH
=0; /* dont halt */
300 bbclk
.WP
=1; /* write protect when we're done */
302 bbclk
.sec10
=tmp
->tm_sec
/10;
303 bbclk
.sec
=tmp
->tm_sec
%10;
305 bbclk
.min10
=tmp
->tm_min
/10;
306 bbclk
.min
=tmp
->tm_min
%10;
308 bbclk
.hr10
=tmp
->tm_hour
/10;
309 bbclk
.hr
=tmp
->tm_hour
%10;
311 bbclk
.day
=tmp
->tm_wday
;
313 bbclk
.date10
=tmp
->tm_mday
/10;
314 bbclk
.date
=tmp
->tm_mday
%10;
316 bbclk
.month10
=tmp
->tm_mon
/10;
317 bbclk
.month
=tmp
->tm_mon
%10;
319 tmp
->tm_year
-= 1900;
320 bbclk
.year10
=tmp
->tm_year
/10;
321 bbclk
.year
=tmp
->tm_year
%10;
323 write_ser_drv(0x8e,&b
,1); /* disable write protect */
324 write_ser_drv(0xbe,(unsigned char *)&bbclk
, 8); /* write burst */