Patch to fix writes to MCS1850 RTC
Cory Bajus <[email protected]> Fri, 21 Apr 2006 18:20:10 -0500
| Newsgroups | gmane.os.netbsd.ports.next68k |
|---|---|
| Message-ID | <[email protected]> |
Attached are patches to use 'burst mode' when writing to the MCS1850 RTC chip. Please test if you get a chance and let me know if there are any problems. Thanks, Cory.
diff-rtc.h
(text/x-chdr, 518 B)
Index: rtc.h =================================================================== RCS file: /cvsroot/src/sys/arch/next68k/next68k/rtc.h,v retrieving revision 1.3 diff -u -r1.3 rtc.h --- rtc.h 19 Jan 2005 01:58:21 -0000 1.3 +++ rtc.h 21 Apr 2006 17:09:20 -0000 @@ -37,7 +37,9 @@ void poweroff(void); void rtc_init(void); u_char rtc_read(u_char); +u_int rtc_read_burst(u_char); void rtc_write(u_char, u_char); +void rtc_write_burst(u_char, u_int); void rtc_print(void); time_t getsecs(void); void setsecs(time_t);
diff-rtc.c
(text/x-csrc, 2.7 KB)
Index: rtc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/next68k/rtc.c,v
retrieving revision 1.13
diff -u -r1.13 rtc.c
--- rtc.c 15 Mar 2006 15:39:26 -0000 1.13
+++ rtc.c 21 Apr 2006 17:17:14 -0000
@@ -162,6 +162,51 @@
return val;
}
+u_int
+rtc_read_burst(u_char reg)
+{
+ int i;
+ u_int tmp, val;
+
+ *scr2 = (*scr2 & ~(SCR2_RTDATA | SCR2_RTCLK)) | SCR2_RTCE;
+ DELAY(1);
+
+ for (i=0; i<8; i++) {
+ tmp = *scr2 & ~(SCR2_RTDATA | SCR2_RTCLK);
+ if (reg & 0x80)
+ tmp |= SCR2_RTDATA;
+
+ *scr2 = tmp;
+ DELAY(1);
+ *scr2 = tmp | SCR2_RTCLK;
+ DELAY(1);
+ *scr2 = tmp;
+ DELAY(1);
+
+ reg <<= 1;
+ }
+
+ val = 0; /* should be anyway */
+ for (i=0; i<32; i++) {
+ val <<= 1;
+
+ tmp = *scr2 & ~(SCR2_RTDATA | SCR2_RTCLK);
+
+ *scr2 = tmp | SCR2_RTCLK;
+ DELAY(1);
+ *scr2 = tmp;
+ DELAY(1);
+
+ if (*scr2 & SCR2_RTDATA)
+ val |= 1;
+ }
+
+ *scr2 &= ~(SCR2_RTDATA|SCR2_RTCLK|SCR2_RTCE);
+ DELAY(1);
+
+ return val;
+}
+
void
rtc_write(u_char reg, u_char v)
{
@@ -211,6 +256,53 @@
}
void
+rtc_write_burst(u_char reg, u_int v)
+{
+ int i;
+ u_int tmp;
+
+ *scr2 = (*scr2 & ~(SCR2_RTDATA | SCR2_RTCLK)) | SCR2_RTCE;
+ DELAY(1);
+
+ reg |= RTC_WRITE;
+
+ for (i=0; i<8; i++) {
+ tmp = *scr2 & ~(SCR2_RTDATA | SCR2_RTCLK);
+ if (reg & 0x80)
+ tmp |= SCR2_RTDATA;
+
+ *scr2 = tmp;
+ DELAY(1);
+ *scr2 = tmp | SCR2_RTCLK;
+ DELAY(1);
+ *scr2 = tmp;
+ DELAY(1);
+
+ reg <<= 1;
+ }
+
+ DELAY(1);
+
+ for (i=0; i<32; i++) {
+ tmp = *scr2 & ~(SCR2_RTDATA | SCR2_RTCLK);
+ if (v & 0x80000000)
+ tmp |= SCR2_RTDATA;
+
+ *scr2 = tmp;
+ DELAY(1);
+ *scr2 = tmp | SCR2_RTCLK;
+ DELAY(1);
+ *scr2 = tmp;
+ DELAY(1);
+
+ v <<= 1;
+ }
+
+ *scr2 &= ~(SCR2_RTDATA|SCR2_RTCLK|SCR2_RTCE);
+ DELAY(1);
+}
+
+void
poweroff(void)
{
int reg, t;
@@ -247,10 +339,7 @@
u_int secs = 0;
if (new_clock) {
- secs = rtc_read(RTC_CNTR0) << 24 |
- rtc_read(RTC_CNTR1) << 16 |
- rtc_read(RTC_CNTR2) << 8 |
- rtc_read(RTC_CNTR3);
+ secs = rtc_read_burst(RTC_CNTR0);
} else {
struct clock_ymdhms val;
{
@@ -296,16 +385,12 @@
rtc_write(RTC_CONTROL,rtc_read(RTC_CONTROL) & ~RTC_START);
#ifdef RTC_DEBUG
- printf("Setting RTC to 0x%08x. Regs before:\n",secs);
+ printf("Setting RTC to 0x%08x. Regs before:\n", (u_int)secs);
rtc_print();
#endif
if (new_clock) {
- rtc_write(RTC_CNTR0, (secs >> 24) & 0xff);
- rtc_write(RTC_CNTR1, (secs >> 16) & 0xff);
- rtc_write(RTC_CNTR2, (secs >> 8) & 0xff);
- rtc_write(RTC_CNTR3, (secs) & 0xff);
-
+ rtc_write_burst(RTC_CNTR0, (u_int)secs);
} else {
struct clock_ymdhms val;
clock_secs_to_ymdhms(secs,&val);
@@ -335,7 +420,7 @@
}
#ifdef RTC_DEBUG
- printf("Regs after:\n",secs);
+ printf("Regs after:\n");
rtc_print();
#endif