1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
/* $OpenBSD: mc146818reg.h,v 1.2 1996/10/31 01:01:34 niklas Exp $ */
/* $NetBSD: mc146818reg.h,v 1.1 1995/05/04 19:31:18 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
/*
* Definitions for the Motorola MC146818A Real Time Clock.
* They also apply for the (compatible) Dallas Semicontuctor DS1287A RTC.
*
* Though there are undoubtedly other (better) sources, this material was
* culled from the DEC "KN121 System Module Programmer's Reference
* Information."
*
* The MC146818A has 16 registers. The first 10 contain time-of-year
* and alarm data. The rest contain various control and status bits.
*
* To read or write the registers, one writes the register number to
* the RTC's control port, then either reads from or writes the new
* data to the RTC's data port. Since the locations of these ports
* and the method used to access them can be machine-dependent, the
* low-level details of reading and writing the RTC's registers are
* handled by machine-specific functions.
*
* The time-of-year and alarm data can be expressed in either binary
* or BCD, and they are selected by a bit in register B.
*
* The "hour" time-of-year and alarm fields can either be expressed in
* AM/PM format, or in 24-hour format. If AM/PM format is chosen, the
* hour fields can have the values: 1-12 and 81-92 (the latter being
* PM). If the 24-hour format is chosen, they can have the values
* 0-24. The hour format is selectable by a bit in register B.
* (XXX IS AM/PM MODE DESCRIPTION CORRECT?)
*
* It is assumed the if systems are going to use BCD (rather than
* binary) mode, or AM/PM hour format, they'll do the appropriate
* conversions in machine-dependent code. Also, if the clock is
* switched between BCD and binary mode, or between AM/PM mode and
* 24-hour mode, the time-of-day and alarm registers are NOT
* automatically reset; they must be reprogrammed with correct values.
*/
/*
* The registers, and the bits within each register.
*/
#define MC_SEC 0x0 /* Time of year: seconds (0-59) */
#define MC_ASEC 0x1 /* Alarm: seconds */
#define MC_MIN 0x2 /* Time of year: minutes (0-59) */
#define MC_AMIN 0x3 /* Alarm: minutes */
#define MC_HOUR 0x4 /* Time of year: hour (see above) */
#define MC_AHOUR 0x5 /* Alarm: hour */
#define MC_DOW 0x6 /* Time of year: day of week (1-7) */
#define MC_DOM 0x7 /* Time of year: day of month (1-31) */
#define MC_MONTH 0x8 /* Time of year: month (1-12) */
#define MC_YEAR 0x9 /* Time of year: year in century (0-99) */
#define MC_REGA 0xa /* Control register A */
#define MC_REGA_RSMASK 0x0f /* Interrupt rate select mask (see below) */
#define MC_REGA_DVMASK 0x70 /* Divisor select mask (see below) */
#define MC_REGA_UIP 0x80 /* Update in progress; read only. */
#define MC_REGB 0xb /* Control register B */
#define MC_REGB_DSE 0x01 /* Daylight Savings Enable */
#define MC_REGB_24HR 0x02 /* 24-hour mode (AM/PM mode when clear) */
#define MC_REGB_BINARY 0x04 /* Binary mode (BCD mode when clear) */
/* MC_REGB_UNUSED 0x08 UNUSED */
#define MC_REGB_UIE 0x10 /* Update End interrupt enable */
#define MC_REGB_AIE 0x20 /* Alarm interrupt enable */
#define MC_REGB_PIE 0x40 /* Periodic interrupt enable */
#define MC_REGB_SET 0x80 /* Allow time to be set; stops updates */
#define MC_REGC 0xc /* Control register C */
/* MC_REGC_UNUSED 0x0f UNUSED */
#define MC_REGC_UF 0x10 /* Update End interrupt flag */
#define MC_REGC_AF 0x20 /* Alarm interrupt flag */
#define MC_REGC_PF 0x40 /* Periodic interrupt flag */
#define MC_REGC_IRQF 0x80 /* Interrupt request pending flag */
#define MC_REGD 0xd /* Control register D */
/* MC_REGD_UNUSED 0x7f UNUSED */
#define MC_REGD_VRT 0x80 /* Valid RAM and Time bit */
#define MC_NREGS 0xe /* 14 registers; CMOS follows */
#define MC_NTODREGS 0xa /* 10 of those regs are for TOD and alarm */
#define MC_NVRAM_START 0xe /* start of NVRAM: offset 14 */
#define MC_NVRAM_SIZE 50 /* 50 bytes of NVRAM */
/*
* Periodic Interrupt Rate Select constants (Control register A)
*/
#define MC_RATE_NONE 0x0 /* No periodic interrupt */
#define MC_RATE_1 0x1 /* 256 Hz if MC_BASE_32_KHz, else 32768 Hz */
#define MC_RATE_2 0x2 /* 128 Hz if MC_BASE_32_KHz, else 16384 Hz */
#define MC_RATE_8192_Hz 0x3 /* 122.070 us period */
#define MC_RATE_4096_Hz 0x4 /* 244.141 us period */
#define MC_RATE_2048_Hz 0x5 /* 488.281 us period */
#define MC_RATE_1024_Hz 0x6 /* 976.562 us period */
#define MC_RATE_512_Hz 0x7 /* 1.953125 ms period */
#define MC_RATE_256_Hz 0x8 /* 3.90625 ms period */
#define MC_RATE_128_Hz 0x9 /* 7.8125 ms period */
#define MC_RATE_64_Hz 0xa /* 15.625 ms period */
#define MC_RATE_32_Hz 0xb /* 31.25 ms period */
#define MC_RATE_16_Hz 0xc /* 62.5 ms period */
#define MC_RATE_8_Hz 0xd /* 125 ms period */
#define MC_RATE_4_Hz 0xe /* 250 ms period */
#define MC_RATE_2_Hz 0xf /* 500 ms period */
/*
* Time base (divisor select) constants (Control register A)
*/
#define MC_BASE_4_MHz 0x00 /* 4MHz crystal */
#define MC_BASE_1_MHz 0x10 /* 1MHz crystal */
#define MC_BASE_32_KHz 0x20 /* 32KHz crystal */
#define MC_BASE_NONE 0x60 /* actually, both of these reset */
#define MC_BASE_RESET 0x70
/*
* RTC register/NVRAM read and write functions -- machine-dependent.
* Appropriately manipulate RTC registers to get/put data values.
*/
u_int mc146818_read __P((void *sc, u_int reg));
void mc146818_write __P((void *sc, u_int reg, u_int datum));
/*
* A collection of TOD/Alarm registers.
*/
typedef u_int mc_todregs[MC_NTODREGS];
/*
* Get all of the TOD/Alarm registers
* Must be called at splhigh(), and with the RTC properly set up.
*/
#define MC146818_GETTOD(sc, regs) \
do { \
int i; \
\
/* update in progress; spin loop */ \
while (mc146818_read(sc, MC_REGA) & MC_REGA_UIP) \
; \
\
/* read all of the tod/alarm regs */ \
for (i = 0; i < MC_NTODREGS; i++) \
(*regs)[i] = mc146818_read(sc, i); \
} while (0);
/*
* Set all of the TOD/Alarm registers
* Must be called at splhigh(), and with the RTC properly set up.
*/
#define MC146818_PUTTOD(sc, regs) \
do { \
int i; \
\
/* stop updates while setting */ \
mc146818_write(sc, MC_REGB, \
mc146818_read(sc, MC_REGB) | MC_REGB_SET); \
\
/* write all of the tod/alarm regs */ \
for (i = 0; i < MC_NTODREGS; i++) \
mc146818_write(sc, i, (*regs)[i]); \
\
/* reenable updates */ \
mc146818_write(sc, MC_REGB, \
mc146818_read(sc, MC_REGB) & ~MC_REGB_SET); \
} while (0);
|