RTC-72421 Support

timer.c is right now a RTC-72421-only version
This commit is contained in:
Oliver Lehmann 2009-08-16 11:11:00 +00:00
parent 79b0a92716
commit 673cc05b09
11 changed files with 247 additions and 45 deletions

View File

@ -0,0 +1,26 @@
#### bauen von sa.timer
make clean
make sa.timer
mv /sa.timer /sa.timer.orig
mv sa.timer /sa.timer
#### Kernel Modul bauen
# altes Zeug weg
make clean
# Objekte bauen
scc -c -O timer.c gmtime.c timegm.c u130.c rtc72421.c
# LIB1 sichern
cp /usr/sys/sys/LIB1 /usr/sys/sys/LIB.orig
# Objekte ins Kernel-Archiv legen
ar rv /usr/sys/sys/LIB1 timer.o rtc72421.o u130.o gmtime.o timegm.o
# Kernel generieren
cd /usr/sys/conf ; make -f make.wega wega
chmod 400 wega ; mv wega /wega.new

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: rtc72421.c,v 1.4 2009/08/12 19:27:31 olivleh1 Exp $ * $Id: rtc72421.c,v 1.5 2009/08/16 11:11:00 olivleh1 Exp $
*/ */
#include <time.h> #include <time.h>
@ -38,14 +38,16 @@ extern struct tm *gmtime();
int int
rtc72421_init() r421init()
{ {
return(0); outb(R421REGD,R421IRQF);
outb(R421REGE,R421CLR);
outb(R421REGF,R4212412);
} }
void void
rtc72421_set(time) r421set(time)
long time; long time;
{ {
struct tm *clktime; struct tm *clktime;
@ -54,24 +56,37 @@ long time;
if(clktime->tm_year > 100) if(clktime->tm_year > 100)
clktime->tm_year -= 100; clktime->tm_year -= 100;
clktime->tm_mon++; clktime->tm_mon++;
outb(R421REGF,R421RST|R421STOP|R4212412);
wrbyte(R421SS1x,R421SSx1,clktime->tm_sec);
wrbyte(R421MI1x,R421MIx1,clktime->tm_min);
wrbyte(R421HH1x,R421HHx1,clktime->tm_hour);
wrbyte(R421DD1x,R421DDx1,clktime->tm_mday);
wrbyte(R421MM1x,R421MMx1,clktime->tm_mon);
wrbyte(R421YY1x,R421YYx1,clktime->tm_year);
} }
void void
rtc72421_start() r421start()
{ {
outb(R421REGF,R4212412);
} }
long long
rtc72421_get() r421get()
{ {
long time; long time = 0;
struct tm *clktime; struct tm *clktime;
clktime->tm_year = 0;
clktime->tm_mday = 0; clktime->tm_sec = rdbyte(R421SS1x,R421SSx1);
clktime->tm_mon = 0; clktime->tm_min = rdbyte(R421MI1x,R421MIx1);
while ((clktime->tm_sec = 0) == 59); clktime->tm_hour = rdbyte(R421HH1x,R421HHx1);
clktime->tm_min = 0; clktime->tm_mday = rdbyte(R421DD1x,R421DDx1);
clktime->tm_hour = 0; clktime->tm_mon = rdbyte(R421MM1x,R421MMx1);
clktime->tm_year = rdbyte(R421YY1x,R421YYx1);
if (clktime->tm_year < 70)
clktime->tm_year+=100;
clktime->tm_mon --;
time = timegm(clktime); time = timegm(clktime);
@ -79,12 +94,33 @@ rtc72421_get()
} }
r421bsy()
{
busy:
outb(R421REGD,R421HOLD);
if( rdnibble(R421REGD) & R421BUSY ) {
outb(R421REGD,R421CLR);
goto busy;
}
outb(R421REGD,R421CLR);
return;
}
void void
wrnibble(addr,nibble) wrnibble(addr,nibble)
unsigned addr; unsigned addr;
int nibble; int nibble;
{ {
outb(addr, nibble);
} }
int
rdnibble(addr)
unsigned addr;
{
return (inb(addr)&~0xf0);
}
void void
wrbyte(addr1,addr2,byte) wrbyte(addr1,addr2,byte)
@ -92,20 +128,22 @@ unsigned addr1;
unsigned addr2; unsigned addr2;
int byte; int byte;
{ {
r421bsy();
wrnibble(addr1,byte/10); wrnibble(addr1,byte/10);
r421bsy();
wrnibble(addr2,byte%10); wrnibble(addr2,byte%10);
} }
int
rdnibble(addr)
unsigned addr;
{
return (0);
}
int int
rdbyte(addr1,addr2) rdbyte(addr1,addr2)
unsigned addr1; unsigned addr1;
unsigned addr2; unsigned addr2;
{ {
return(rdnibble(addr1) + rdnibble(addr2)*10); register a,b;
r421bsy();
a=rdnibble(addr2);
r421bsy();
b=rdnibble(addr1);
return(a + b*10);
} }

View File

@ -23,14 +23,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: rtc72421.h,v 1.4 2009/08/12 19:27:31 olivleh1 Exp $ * $Id: rtc72421.h,v 1.5 2009/08/16 11:11:00 olivleh1 Exp $
*/ */
#ifndef R421_H #ifndef R421_H
#define R421_H 1 #define R421_H 1
#define STR_R421 0xc #define STR_R421 0x30
#define MSK_R421 0xf0 #define MSK_R421 0x0f
#define R421BASE 0xfde1 /* base address */ #define R421BASE 0xfde1 /* base address */
#define R421YYx1 0xfdf5 /* 1-year digit register */ #define R421YYx1 0xfdf5 /* 1-year digit register */
@ -50,6 +50,8 @@
#define R421REGE 0xfdfd /* t1, t0, ITRPT/STND, MASK */ #define R421REGE 0xfdfd /* t1, t0, ITRPT/STND, MASK */
#define R421REGF 0xfdff /* TEST, 24/12, STOP, RESET */ #define R421REGF 0xfdff /* TEST, 24/12, STOP, RESET */
#define R421CLR 0x00
/* register F */ /* register F */
#define R421RST 0x01 #define R421RST 0x01
#define R421STOP 0x02 #define R421STOP 0x02
@ -62,9 +64,9 @@
#define R421IRQF 0x04 #define R421IRQF 0x04
#define R421ADJ 0x08 #define R421ADJ 0x08
int rtc72421_init(); int r421init();
long rtc72421_get(); long r421get();
void rtc72421_set(); void r421set();
void rtc72421_start(); void r421start();
#endif #endif

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: timer.h,v 1.3 2009/08/12 19:27:31 olivleh1 Exp $ * $Id: timer.h,v 1.4 2009/08/16 11:11:00 olivleh1 Exp $
*/ */
#ifndef TIMER_H #ifndef TIMER_H
@ -47,11 +47,11 @@ char estring[20];
static struct clock_type clock_devs[] = { static struct clock_type clock_devs[] = {
{ U130BASE, MSK_U130, STR_U130, 80, 119, { U130BASE, MSK_U130, STR_U130, 80, 119,
"RFT U130X RTC", "RFT U130X RTC",
u130_init, u130_get, u130_set, u130_start u130init, u130get, u130set, u130start
}, },
{ R421BASE, MSK_R421, STR_R421, 70, 137, { R421BASE, MSK_R421, STR_R421, 70, 137,
"Seiko Epson RTC-72421", "Seiko Epson RTC-72421",
rtc72421_init, rtc72421_get, rtc72421_set, rtc72421_start r421init, r421get, r421set, r421start
}, },
}; };

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: u130.c,v 1.9 2009/08/12 19:27:31 olivleh1 Exp $ * $Id: u130.c,v 1.10 2009/08/16 11:11:00 olivleh1 Exp $
*/ */
#include <time.h> #include <time.h>
@ -36,13 +36,13 @@ long timegm();
struct tm *gmtime(); struct tm *gmtime();
int int
u130_init() u130init()
{ {
return(0); return(0);
} }
void void
u130_set(time) u130set(time)
long time; long time;
{ {
struct tm *clktime; struct tm *clktime;
@ -99,14 +99,14 @@ long time;
} }
void void
u130_start() u130start()
{ {
outvalue(0x01); /* Start der Zeit */ outvalue(0x01); /* Start der Zeit */
outvalue(0x00); outvalue(0x00);
} }
long long
u130_get() u130get()
{ {
long time; long time;
struct tm *clktime; struct tm *clktime;

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: u130.h,v 1.4 2009/08/12 19:27:31 olivleh1 Exp $ * $Id: u130.h,v 1.5 2009/08/16 11:11:00 olivleh1 Exp $
*/ */
#ifndef U130_H #ifndef U130_H
@ -46,9 +46,9 @@
#define U130MIx1 0xfef9 /* 1-minute digit register */ #define U130MIx1 0xfef9 /* 1-minute digit register */
#define U130MI1x 0xfefb /* 10-minute digit register */ #define U130MI1x 0xfefb /* 10-minute digit register */
int u130_init(); int u130init();
long u130_get(); long u130get();
void u130_set(); void u130set();
void u130_start(); void u130start();
#endif #endif

View File

@ -1,4 +1,4 @@
OBJ= sa.timer.o libb.a u130.o rtc72421.o gmtime.o timegm.o OBJ= sa.timer.o timer.o libb.a u130.o rtc72421.o gmtime.o timegm.o
CC= cc CC= cc
LD= ld LD= ld
DEBUG= DEBUG=

View File

@ -0,0 +1,137 @@
/*-
* Copyright (c) 2009 Oliver Lehmann <oliver@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* 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 $
*/
#include "time.h"
#include "rtc72421.h"
void wrnibble();
void wrbyte();
int rdnibble();
int rdbyte();
static int dmsize[] = /* Tage/Monat (kumulierend) */
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
long
gettime()
{
register long time;
register d1, d2, d3;
register i;
time = 0;
r421init();
d1 = rdbyte(R421YY1x,R421YYx1); /* Jahr */
d2 = rdbyte(R421DD1x,R421DDx1); /* Tag */
d3 = rdbyte(R421MM1x,R421MMx1); /* Monat */
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;
while ((d1 = rdbyte(R421SS1x,R421SSx1)) == 59)
; /* Sekunden */
d2 = rdbyte(R421MI1x,R421MIx1); /* Minuten */
d3 = rdbyte(R421HH1x,R421HHx1); /* Stunden */
if (d1 > 59 || d2 > 59 || d3 > 23)
return(time);
time = 24*time + d3;
time = 60*time + d2;
time = 60*time + d1;
return(time);
}
r421init()
{
outb(R421REGD,R421IRQF);
outb(R421REGE,R421CLR);
outb(R421REGF,R4212412);
}
r421bsy()
{
busy:
outb(R421REGD,R421HOLD);
if( rdnibble(R421REGD) & R421BUSY ) {
outb(R421REGD,R421CLR);
goto busy;
}
outb(R421REGD,R421CLR);
return;
}
void
wrnibble(addr,nibble)
unsigned addr;
int nibble;
{
outb(addr, nibble);
}
int
rdnibble(addr)
unsigned addr;
{
return (inb(addr)&~0xf0);
}
void
wrbyte(addr1,addr2,byte)
unsigned addr1;
unsigned addr2;
int byte;
{
r421bsy();
wrnibble(addr1,byte/10);
r421bsy();
wrnibble(addr2,byte%10);
}
int
rdbyte(addr1,addr2)
unsigned addr1;
unsigned addr2;
{
register a,b;
r421bsy();
a=rdnibble(addr2);
r421bsy();
b=rdnibble(addr1);
return(a + b*10);
}

View File

@ -1,4 +1,4 @@
OBJ= sa.timer.o libb.a u130.o rtc72421.o gmtime.o timegm.o OBJ= sa.timer.o timer.o libb.a u130.o rtc72421.o gmtime.o timegm.o
CC= cc CC= cc
LD= ld LD= ld
DEBUG= DEBUG=

View File

@ -1,4 +1,4 @@
OBJ= sa.timer.o libb.a u130.o rtc72421.o gmtime.o timegm.o OBJ= sa.timer.o timer.o libb.a u130.o rtc72421.o gmtime.o timegm.o
CC= cc CC= cc
LD= ld LD= ld
DEBUG= DEBUG=

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: sa.timer.c,v 1.10 2009/08/12 19:27:31 olivleh1 Exp $ * $Id: sa.timer.c,v 1.11 2009/08/16 11:11:00 olivleh1 Exp $
*/ */
@ -34,7 +34,6 @@
long timegm(); long timegm();
struct tm *gmtime(); struct tm *gmtime();
long u130_get();
int clock_min_year; int clock_min_year;
int clock_max_year; int clock_max_year;