Subject: Patch to fix writes to MCS1850 RTC
To: None <port-next68k@netbsd.org>
From: Cory Bajus <cbajus@mts.net>
List: port-next68k
Date: 04/21/2006 18:20:10
--yrj/dFKFPuw6o+aM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
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.
--yrj/dFKFPuw6o+aM
Content-Type: text/x-chdr; charset=us-ascii
Content-Disposition: attachment; filename="diff-rtc.h"
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);
--yrj/dFKFPuw6o+aM
Content-Type: text/x-csrc; charset=us-ascii
Content-Disposition: attachment; filename="diff-rtc.c"
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
--yrj/dFKFPuw6o+aM--