* Make the rtc and the clock real devices. Initialize the clock parts
of the ICU in clock_attach. * Pull over (and reformat) rtc_rw from mem.c. * Convert the rtc driver to use /sys/dev/clock_subr.c (partially by stealing code from the sun3 port).
This commit is contained in:
parent
fa30cfc066
commit
b677f20e5d
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: clock.c,v 1.18 1997/01/15 01:28:56 perry Exp $ */
|
/* $NetBSD: clock.c,v 1.19 1997/03/20 12:00:33 matthias Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1990 The Regents of the University of California.
|
* Copyright (c) 1990 The Regents of the University of California.
|
||||||
|
@ -39,48 +39,125 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Primitive clock interrupt routines.
|
|
||||||
*
|
|
||||||
* Improved by Phil Budne ... 10/17/94.
|
|
||||||
* Pulled over code from i386/isa/clock.c (Matthias Pfaller 12/03/94).
|
|
||||||
* Phil Budne's better microtime added 09/02/96
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
#include <sys/device.h>
|
||||||
|
#include <sys/conf.h>
|
||||||
|
|
||||||
|
#include <dev/clock_subr.h>
|
||||||
|
|
||||||
|
#include <machine/autoconf.h>
|
||||||
#include <machine/icu.h>
|
#include <machine/icu.h>
|
||||||
|
|
||||||
|
#define ROM_ORIGIN 0xFFF00000 /* Mapped origin! */
|
||||||
|
static volatile u_char * const rom = (u_char *)ROM_ORIGIN;
|
||||||
static int divisor;
|
static int divisor;
|
||||||
|
static int clockinitted;
|
||||||
|
static int rtc_attached;
|
||||||
|
static u_char rtc_magic[8] = {
|
||||||
|
0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c
|
||||||
|
};
|
||||||
|
|
||||||
void
|
static long clk_get_secs __P((void));
|
||||||
startrtclock()
|
static void clk_set_secs __P((long));
|
||||||
|
static u_char bcd2bin __P((u_char));
|
||||||
|
static u_char bin2bcd __P((u_char));
|
||||||
|
static void rw_rtc __P((struct clock_ymdhms *, int));
|
||||||
|
static void write_rtc __P((u_char *));
|
||||||
|
|
||||||
|
static int clock_match __P((struct device *, struct cfdata *, void *args));
|
||||||
|
static void clock_attach __P((struct device *, struct device *, void *));
|
||||||
|
|
||||||
|
struct cfattach clock_ca = {
|
||||||
|
sizeof(struct device), clock_match, clock_attach
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cfdriver clock_cd = {
|
||||||
|
NULL, "clock", DV_DULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rtc_match __P((struct device *, struct cfdata *, void *args));
|
||||||
|
static void rtc_attach __P((struct device *, struct device *, void *));
|
||||||
|
|
||||||
|
struct cfattach rtc_ca = {
|
||||||
|
sizeof(struct device), rtc_match, rtc_attach
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cfdriver rtc_cd = {
|
||||||
|
NULL, "rtc", DV_DULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
clock_match(parent, cf, aux)
|
||||||
|
struct device *parent;
|
||||||
|
struct cfdata *cf;
|
||||||
|
void *aux;
|
||||||
{
|
{
|
||||||
|
struct confargs *ca = aux;
|
||||||
|
|
||||||
|
/* This driver only supports one unit. */
|
||||||
|
if (cf->cf_unit != 0)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if ((ca->ca_addr != -1 && ca->ca_addr != ICU_ADR) ||
|
||||||
|
(ca->ca_irq != -1 && ca->ca_irq != IR_CLK))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
ca->ca_addr = ICU_ADR;
|
||||||
|
ca->ca_irq = IR_CLK;
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clock_attach(parent, self, aux)
|
||||||
|
struct device *parent;
|
||||||
|
struct device *self;
|
||||||
|
void *aux;
|
||||||
|
{
|
||||||
|
struct confargs *ca = aux;
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
divisor = ICU_CLK_HZ / hz;
|
divisor = ICU_CLK_HZ / hz;
|
||||||
|
|
||||||
/* Write the timer values to the ICU. */
|
/* Disable clock interrupt for now. */
|
||||||
ICUW(HCSV) = divisor;
|
ICUB(CICTL) = 0;
|
||||||
ICUW(HCCV) = divisor;
|
|
||||||
|
/* Select clock interrupt vector. */
|
||||||
|
ICUB(CIPTR) = ca->ca_irq << 4;
|
||||||
|
|
||||||
/* Establish interrupt vector */
|
/* Establish interrupt vector */
|
||||||
intr_establish(IR_CLK, (void (*)(void *))hardclock, NULL, "clock",
|
intr_establish(IR_CLK, (void (*)(void *))hardclock, NULL, "clock",
|
||||||
IPL_CLOCK, IPL_CLOCK, FALLING_EDGE);
|
IPL_CLOCK, IPL_CLOCK, FALLING_EDGE);
|
||||||
|
|
||||||
|
/* No clock output. */
|
||||||
|
ICUB(OCASN) = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Two clocks, prescale, output zero detect of L-counter,
|
||||||
|
* run both clocks.
|
||||||
|
*/
|
||||||
|
ICUB(CCTL) = 0x1c;
|
||||||
|
|
||||||
|
/* Write the timer values to the ICU. */
|
||||||
|
ICUW(HCSV) = divisor;
|
||||||
|
ICUW(HCCV) = divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cpu_initclocks()
|
cpu_initclocks()
|
||||||
{
|
{
|
||||||
/* Enable clock interrupt. */
|
/* Enable the clock interrupt. */
|
||||||
ICUB(CICTL) = 0x30;
|
ICUB(CICTL) = 0x30;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setstatclockrate(int dummy)
|
setstatclockrate(arg)
|
||||||
|
int arg;
|
||||||
{
|
{
|
||||||
printf ("setstatclockrate\n");
|
printf("setstatclockrate\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -111,154 +188,273 @@ microtime(tvp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
/*
|
||||||
|
* Machine-dependent clock routines.
|
||||||
|
*
|
||||||
|
* Inittodr initializes the time of day hardware which provides
|
||||||
|
* date functions.
|
||||||
|
*
|
||||||
|
* Resettodr restores the time of day hardware after a time change.
|
||||||
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
yeartoday(year)
|
rtc_match(parent, cf, aux)
|
||||||
int year;
|
struct device *parent;
|
||||||
|
struct cfdata *cf;
|
||||||
|
void *aux;
|
||||||
{
|
{
|
||||||
|
struct confargs *ca = aux;
|
||||||
|
int rom_val, rom_cnt, i;
|
||||||
|
|
||||||
return((year % 4) ? 365 : 366);
|
/* This driver only supports one unit. */
|
||||||
|
if (cf->cf_unit != 0)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
(void) rom[4]; /* Synchronize the comparison reg. */
|
||||||
|
rom_val = rom[4];
|
||||||
|
write_rtc(rtc_magic);
|
||||||
|
|
||||||
|
for (i = rom_cnt = 0; i < 64; i++)
|
||||||
|
if (rom[4] == rom_val)
|
||||||
|
rom_cnt++;
|
||||||
|
|
||||||
|
if (rom_cnt == 64)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if ((ca->ca_addr != -1 && ca->ca_addr != ROM_ORIGIN) ||
|
||||||
|
ca->ca_irq != -1)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
ca->ca_addr = ROM_ORIGIN;
|
||||||
|
ca->ca_irq = -1;
|
||||||
|
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static void
|
||||||
hexdectodec(n)
|
rtc_attach(parent, self, aux)
|
||||||
char n;
|
struct device *parent;
|
||||||
|
struct device *self;
|
||||||
|
void *aux;
|
||||||
{
|
{
|
||||||
|
printf("\n");
|
||||||
return(((n >> 4) & 0x0F) * 10 + (n & 0x0F));
|
rtc_attached = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char
|
|
||||||
dectohexdec(n)
|
|
||||||
int n;
|
|
||||||
{
|
|
||||||
|
|
||||||
return((char)(((n / 10) << 4) & 0xF0) | ((n % 10) & 0x0F));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int timeset;
|
|
||||||
struct rtc_st {
|
|
||||||
unsigned char rtc_csec;
|
|
||||||
unsigned char rtc_sec;
|
|
||||||
unsigned char rtc_min;
|
|
||||||
unsigned char rtc_hr;
|
|
||||||
unsigned char rtc_dow;
|
|
||||||
unsigned char rtc_dom;
|
|
||||||
unsigned char rtc_mon;
|
|
||||||
unsigned char rtc_yr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the time of day register, based on the time base which is, e.g.
|
* Initialize the time of day register, based on the time base
|
||||||
* from a filesystem.
|
* which is, e.g. from a filesystem.
|
||||||
*/
|
*/
|
||||||
void
|
void inittodr(fs_time)
|
||||||
inittodr(base)
|
time_t fs_time;
|
||||||
time_t base;
|
|
||||||
{
|
{
|
||||||
/*
|
long diff, clk_time;
|
||||||
* We ignore the suggested time for now and go for the RTC
|
long long_ago = (5 * SECYR);
|
||||||
* clock time stored in the CMOS RAM.
|
int clk_bad = 0;
|
||||||
*/
|
|
||||||
struct rtc_st rtclk;
|
|
||||||
time_t n;
|
|
||||||
int csec, sec, min, hr, dom, mon, yr;
|
|
||||||
int i, days = 0;
|
|
||||||
int s;
|
|
||||||
extern int have_rtc;
|
|
||||||
|
|
||||||
timeset = 1;
|
clockinitted = 1;
|
||||||
if (!have_rtc) {
|
|
||||||
time.tv_sec = base;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rw_rtc((unsigned char *)&rtclk, 0);
|
|
||||||
|
|
||||||
csec = hexdectodec(rtclk.rtc_csec);
|
|
||||||
sec = hexdectodec(rtclk.rtc_sec);
|
|
||||||
min = hexdectodec(rtclk.rtc_min);
|
|
||||||
hr = hexdectodec(rtclk.rtc_hr);
|
|
||||||
dom = hexdectodec(rtclk.rtc_dom);
|
|
||||||
mon = hexdectodec(rtclk.rtc_mon);
|
|
||||||
yr = hexdectodec(rtclk.rtc_yr);
|
|
||||||
yr = (yr < 70) ? yr + 100 : yr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check to see if it was really the rtc
|
* Sanity check time from file system.
|
||||||
* by checking for bad date info.
|
* If it is zero,assume filesystem time is just unknown
|
||||||
|
* instead of preposterous. Don't bark.
|
||||||
*/
|
*/
|
||||||
if (sec > 59 || min > 59 || hr > 23 || dom > 31 || mon > 12) {
|
if (fs_time < long_ago) {
|
||||||
printf("inittodr: No clock found\n");
|
/*
|
||||||
time.tv_sec = base;
|
* If fs_time is zero, assume filesystem time is just
|
||||||
return;
|
* unknown instead of preposterous. Don't bark.
|
||||||
|
*/
|
||||||
|
if (fs_time != 0)
|
||||||
|
printf("WARNING: preposterous time in file system\n");
|
||||||
|
/* 1991/07/01 12:00:00 */
|
||||||
|
fs_time = 21*SECYR + 186*SECDAY + SECDAY/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = sec + 60 * min + 3600 * hr;
|
clk_time = clk_get_secs();
|
||||||
n += (dom - 1) * 3600 * 24;
|
|
||||||
|
|
||||||
if (yeartoday(yr) == 366)
|
/* Sanity check time from clock. */
|
||||||
month[1] = 29;
|
if (clk_time < long_ago) {
|
||||||
for (i = mon - 2; i >= 0; i--)
|
printf("WARNING: bad date in battery clock");
|
||||||
days += month[i];
|
clk_bad = 1;
|
||||||
month[1] = 28;
|
clk_time = fs_time;
|
||||||
for (i = 70; i < yr; i++)
|
} else {
|
||||||
days += yeartoday(i);
|
/* Does the clock time jive with the file system? */
|
||||||
n += days * 3600 * 24;
|
diff = clk_time - fs_time;
|
||||||
|
if (diff < 0)
|
||||||
n += rtc_offset * 60;
|
diff = -diff;
|
||||||
s = splclock();
|
if (diff >= (SECDAY*2)) {
|
||||||
time.tv_sec = n;
|
printf("WARNING: clock %s %d days",
|
||||||
time.tv_usec = csec * 10000;
|
(clk_time < fs_time) ? "lost" : "gained",
|
||||||
splx(s);
|
(int) (diff / SECDAY));
|
||||||
|
clk_bad = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (clk_bad)
|
||||||
|
printf(" -- CHECK AND RESET THE DATE!\n");
|
||||||
|
time.tv_sec = clk_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset the clock.
|
* Resettodr restores the time of day hardware after a time change.
|
||||||
*/
|
*/
|
||||||
void
|
void resettodr()
|
||||||
resettodr()
|
|
||||||
{
|
{
|
||||||
struct rtc_st rtclk;
|
|
||||||
time_t n;
|
|
||||||
int diff, i, j;
|
|
||||||
int s;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We might have been called by boot() due to a crash early
|
* We might have been called by boot() due to a crash early
|
||||||
* on. Don't reset the clock chip in this case.
|
* on. Don't reset the clock chip in this case.
|
||||||
*/
|
*/
|
||||||
if (!timeset)
|
if (clockinitted == 0)
|
||||||
|
return;
|
||||||
|
clk_set_secs(time.tv_sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now routines to get and set clock as POSIX time.
|
||||||
|
* Our clock keeps "years since 1/1/1900".
|
||||||
|
*/
|
||||||
|
#define CLOCK_BASE_YEAR 1900
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the actual reading and writing of the rtc. We have to read
|
||||||
|
* and write the entire contents at a time.
|
||||||
|
* rw = 0 => read,
|
||||||
|
* rw = 1 => write.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static u_char
|
||||||
|
bcd2bin(n)
|
||||||
|
u_char n;
|
||||||
|
{
|
||||||
|
return(((n >> 4) & 0x0f) * 10 + (n & 0x0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
static u_char
|
||||||
|
bin2bcd(n)
|
||||||
|
u_char n;
|
||||||
|
{
|
||||||
|
return((char)(((n / 10) << 4) & 0xf0) | ((n % 10) & 0x0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_rtc(p)
|
||||||
|
u_char *p;
|
||||||
|
{
|
||||||
|
u_char *q;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (q = p + 8; p < q; p++) {
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
(void) rom[(*p >> i) & 0x01];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rw_rtc(dt, rw)
|
||||||
|
struct clock_ymdhms *dt;
|
||||||
|
int rw;
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
u_char rtc_csec;
|
||||||
|
u_char rtc_sec;
|
||||||
|
u_char rtc_min;
|
||||||
|
u_char rtc_hour;
|
||||||
|
u_char rtc_wday;
|
||||||
|
u_char rtc_day;
|
||||||
|
u_char rtc_mon;
|
||||||
|
u_char rtc_year;
|
||||||
|
} rtcdt[1];
|
||||||
|
u_char *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read or write to the real time chip. Address line A0 functions as
|
||||||
|
* data input, A2 is used as the /write signal. Accesses to the RTC
|
||||||
|
* are always done to one of the addresses (unmapped):
|
||||||
|
*
|
||||||
|
* 0x10000000 - write a '0' bit
|
||||||
|
* 0x10000001 - write a '1' bit
|
||||||
|
* 0x10000004 - read a bit
|
||||||
|
*
|
||||||
|
* Data is output from the RTC using D0. To read or write time
|
||||||
|
* information, the chip has to be activated first, to distinguish
|
||||||
|
* clock accesses from normal ROM reads. This is done by writing,
|
||||||
|
* bit by bit, a magic pattern to the chip. Before that, a dummy read
|
||||||
|
* assures that the chip's pattern comparison register pointer is
|
||||||
|
* reset. The RTC register file is always read or written wholly,
|
||||||
|
* even if we are only interested in a part of it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Activate the real time chip */
|
||||||
|
(void) rom[4]; /* Synchronize the comparison reg. */
|
||||||
|
write_rtc(rtc_magic);
|
||||||
|
|
||||||
|
if (rw == 0) {
|
||||||
|
/* Read the time from the RTC. */
|
||||||
|
for (p = (u_char *)rtcdt; p < (u_char *)(rtcdt + 1); p++) {
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
*p >>= 1;
|
||||||
|
*p |= ((rom[4] & 0x01) ? 0x80 : 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dt->dt_sec = bcd2bin(rtcdt->rtc_sec);
|
||||||
|
dt->dt_min = bcd2bin(rtcdt->rtc_min);
|
||||||
|
dt->dt_hour = bcd2bin(rtcdt->rtc_hour);
|
||||||
|
dt->dt_day = bcd2bin(rtcdt->rtc_day);
|
||||||
|
dt->dt_mon = bcd2bin(rtcdt->rtc_mon);
|
||||||
|
dt->dt_year = bcd2bin(rtcdt->rtc_year);
|
||||||
|
dt->dt_wday = bcd2bin(rtcdt->rtc_wday);
|
||||||
|
} else {
|
||||||
|
/* Write the time to the RTC */
|
||||||
|
rtcdt->rtc_sec = bin2bcd(dt->dt_sec);
|
||||||
|
rtcdt->rtc_min = bin2bcd(dt->dt_min);
|
||||||
|
rtcdt->rtc_hour = bin2bcd(dt->dt_hour);
|
||||||
|
rtcdt->rtc_day = bin2bcd(dt->dt_day);
|
||||||
|
rtcdt->rtc_mon = bin2bcd(dt->dt_mon);
|
||||||
|
rtcdt->rtc_year = bin2bcd(dt->dt_year);
|
||||||
|
rtcdt->rtc_wday = bin2bcd(dt->dt_wday);
|
||||||
|
write_rtc((u_char *)rtcdt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
clk_get_secs()
|
||||||
|
{
|
||||||
|
struct clock_ymdhms dt;
|
||||||
|
long secs;
|
||||||
|
|
||||||
|
if (rtc_attached == 0)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
rw_rtc(&dt, 0);
|
||||||
|
if ((dt.dt_sec > 59) ||
|
||||||
|
(dt.dt_min > 59) ||
|
||||||
|
(dt.dt_hour > 23) ||
|
||||||
|
(dt.dt_day > 31) ||
|
||||||
|
(dt.dt_mon > 12) ||
|
||||||
|
(dt.dt_year > 99))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if (dt.dt_year < 70)
|
||||||
|
dt.dt_year += 100;
|
||||||
|
|
||||||
|
dt.dt_year += CLOCK_BASE_YEAR;
|
||||||
|
secs = clock_ymdhms_to_secs(&dt);
|
||||||
|
return(secs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clk_set_secs(secs)
|
||||||
|
long secs;
|
||||||
|
{
|
||||||
|
struct clock_ymdhms dt;
|
||||||
|
|
||||||
|
if (rtc_attached == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
diff = rtc_offset * 60;
|
clock_secs_to_ymdhms(secs, &dt);
|
||||||
|
dt.dt_year -= CLOCK_BASE_YEAR;
|
||||||
|
if (dt.dt_year >= 100)
|
||||||
|
dt.dt_year -= 100;
|
||||||
|
|
||||||
s = splclock();
|
rw_rtc(&dt, 1);
|
||||||
n = (time.tv_sec - diff) % (3600 * 24); /* hrs+mins+secs */
|
|
||||||
rtclk.rtc_csec = dectohexdec(time.tv_usec / 10000);
|
|
||||||
rtclk.rtc_sec = dectohexdec(n%60);
|
|
||||||
n /= 60;
|
|
||||||
rtclk.rtc_min = dectohexdec(n%60);
|
|
||||||
rtclk.rtc_hr = dectohexdec(n/60);
|
|
||||||
|
|
||||||
n = (time.tv_sec - diff) / (3600 * 24); /* days */
|
|
||||||
splx(s);
|
|
||||||
rtclk.rtc_dow = (n + 4) % 7; /* 1/1/70 is Thursday */
|
|
||||||
|
|
||||||
for (j = 1970, i = yeartoday(j); n >= i; j++, i = yeartoday(j))
|
|
||||||
n -= i;
|
|
||||||
|
|
||||||
rtclk.rtc_yr = dectohexdec(j - 1900);
|
|
||||||
|
|
||||||
if (i == 366)
|
|
||||||
month[1] = 29;
|
|
||||||
for (i = 0; n >= month[i]; i++)
|
|
||||||
n -= month[i];
|
|
||||||
month[1] = 28;
|
|
||||||
rtclk.rtc_mon = dectohexdec(++i);
|
|
||||||
|
|
||||||
rtclk.rtc_dom = dectohexdec(++n);
|
|
||||||
|
|
||||||
rw_rtc((unsigned char *)&rtclk, 1);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue