From 9c5fe2127af6cb05054fd40521d34e4013b22881 Mon Sep 17 00:00:00 2001 From: Oliver Lehmann Date: Sun, 16 Aug 2009 11:49:51 +0000 Subject: [PATCH] working version --- .../cmd/standalone/sa.timer/kernel/timer.c | 136 +++++++++++++++++- 1 file changed, 133 insertions(+), 3 deletions(-) diff --git a/WEGA/src/cmd/standalone/sa.timer/kernel/timer.c b/WEGA/src/cmd/standalone/sa.timer/kernel/timer.c index 1c34e09..d450863 100644 --- a/WEGA/src/cmd/standalone/sa.timer/kernel/timer.c +++ b/WEGA/src/cmd/standalone/sa.timer/kernel/timer.c @@ -23,23 +23,27 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: timer.c,v 1.1 2009/08/16 11:11:00 olivleh1 Exp $ + * $Id: timer.c,v 1.2 2009/08/16 11:49:51 olivleh1 Exp $ */ -#include "time.h" +#include #include "rtc72421.h" +#include "u130.h" void wrnibble(); void wrbyte(); int rdnibble(); int rdbyte(); +int rdvalue(); +int invalue(); +void outvalue(); static int dmsize[] = /* Tage/Monat (kumulierend) */ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; long -gettime() +r421time() { register long time; register d1, d2, d3; @@ -73,7 +77,71 @@ gettime() return(time); } +long +u130time() +{ + register long time; + register d1, d2, d3; + register i; + time = 0; + if (inb(0xfef1) != 0xbf) /* Uhrmodul vorhanden ? */ + return(time); + outvalue(0x02); /* Umschalten auf Datum */ + d1 = rdvalue(0xfef5); /* Jahr */ + d2 = rdvalue(0xfef9); /* Tag */ + d3 = rdvalue(0xfefd); /* Monat */ + outvalue(0x00); + if (d1 > 100 || d2 > 31 || d3 > 12) + return(time); + i = dmsize[d3-1]; + if (d1%4 == 0 && d3 > 2) i++; + if (d1 < 70) d1 += 100; + if (d1 > 137) return(time); + time = (d1-69)/4; + time += 365*(d1-70)+i; + time += d2 - 1; + + d1 = inb(0xfeff) & 0x28; /* Umschalten auf Zeit */ + if (d1 == 0x08 || d1 == 0x20) { + outvalue(0x02); + outvalue(0x00); + } + while ((d1 = rdvalue(0xfef5)) == 59) + ; /* Sekunden */ + d2 = rdvalue(0xfef9); /* Minuten */ + d3 = rdvalue(0xfefd); /* Stunden */ + if (d1 > 59 || d2 > 59 || d3 > 23) + return(time); + time = 24*time + d3; + time = 60*time + d2; + time = 60*time + d1; + return(time); +} + +long +gettime() +{ + register long time; + int a,b; + + time = 0; + a = inb(U130BASE)&~MSK_U130; + b = STR_U130; + if( a == b) { + printf("RFT U130X RTC found\n"); + time = u130time(); + } else { + a = inb(R421BASE)&~MSK_R421; + b = STR_R421; + if( a == b) { + printf("Seiko Epson RTC-72421\n"); + time = r421time(); + } + } + + return(time); +} r421init() { @@ -135,3 +203,65 @@ unsigned addr2; b=rdnibble(addr1); return(a + b*10); } + +void +outvalue(t) +register t; +{ + outb(U130BASE, t); + t = 10000; + while (t--) + ; +} + +int +invalue(addr, flag) +register addr; +register flag; +{ + register seg7, takt; + + seg7 = inb(addr); + if (seg7 != inb(addr)) + seg7 = inb(addr); + takt = seg7 & 0x80; /* nur gueltig bei 6. Stelle */ + if (seg7 & 0x20) + seg7 = ~seg7; + if (addr == U130MM1x) /* 6.Stelle */ + seg7 &= 0x07; + seg7 &= 0x1f; + if (seg7 == 0x0f) + return(0); + if (seg7 == 0x00) { + if (flag == 0) + return(0); + if (addr == U130MM1x && takt) + return(0); + } + if (seg7 == 0x02) + return(1); + if (seg7 == 0x17 || seg7 == 0x05) + return(2); + if (seg7 == 0x13) + return(3); + if (seg7 == 0x1a) + return(4); + if (seg7 == 0x19) + return(5); + if (seg7 == 0x1d) + return(6); + if (seg7 == 0x03) + return(7); + if (seg7 == 0x1f) + return(8); + if (seg7 == 0x1b) + return(9); + return(0xff); +} + +int +rdvalue(addr) +unsigned addr; +{ + return(invalue(addr,0) + invalue(addr+2,0)*10); +}