source: rtems/c/src/lib/libbsp/i386/pc386/clock/rtc.c @ 7150f00f

4.104.114.84.95
Last change on this file since 7150f00f was 7150f00f, checked in by Joel Sherrill <joel.sherrill@…>, on Dec 1, 1997 at 10:06:48 PM

Inclusion of PC386 BSP submitted by Pedro Miguel Da Cruz Neto Romano
<pmcnr@…> and Jose Rufino <ruf@…>
of NavIST (http://pandora.ist.utl.pt/).

  • Property mode set to 100644
File size: 9.1 KB
Line 
1/*-------------------------------------------------------------------------+
2| rtc.c v1.1 - PC386 BSP - 1997/08/07
3+--------------------------------------------------------------------------+
4| This file contains the real time clock manipulation package for the
5| PC386 board.
6+--------------------------------------------------------------------------+
7| (C) Copyright 1997 -
8| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
9|
10| http://pandora.ist.utl.pt
11|
12| Instituto Superior Tecnico * Lisboa * PORTUGAL
13+--------------------------------------------------------------------------+
14| Disclaimer:
15|
16| This file is provided "AS IS" without warranty of any kind, either
17| expressed or implied.
18+--------------------------------------------------------------------------+
19| This code is based on:
20|   rtc.c,v 1.4 1995/12/19 20:07:15 joel Exp - go32 BSP
21| With the following copyright notice:
22| **************************************************************************
23| * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.                      *
24| * On-Line Applications Research Corporation (OAR).                       *
25| * All rights assigned to U.S. Government, 1994.                          *
26| *                                                                        *
27| * This material may be reproduced by or for the U.S. Government pursuant *
28| * to the copyright license under the clause at DFARS 252.227-7013.  This *
29| * notice must appear in all copies of this file and its derivatives.     *
30| **************************************************************************
31+--------------------------------------------------------------------------*/
32
33
34#include <string.h>
35
36#include <bsp.h>
37
38/*-------------------------------------------------------------------------+
39| Constants
40+--------------------------------------------------------------------------*/
41#define IO_RTC         0x70  /* RTC                                    */
42
43#define RTC_SEC        0x00  /* seconds                                */
44#define RTC_SECALRM    0x01  /* seconds alarm                          */
45#define RTC_MIN        0x02  /* minutes                                */
46#define RTC_MINALRM    0x03  /* minutes alarm                          */
47#define RTC_HRS        0x04  /* hours                                  */
48#define RTC_HRSALRM    0x05  /* hours alarm                            */
49#define RTC_WDAY       0x06  /* week day                               */
50#define RTC_DAY        0x07  /* day of month                           */
51#define RTC_MONTH      0x08  /* month of year                          */
52#define RTC_YEAR       0x09  /* month of year                          */
53#define RTC_STATUSA    0x0a  /* status register A                      */
54#define  RTCSA_TUP     0x80  /* time update, don't look now            */
55
56#define RTC_STATUSB    0x0b  /* status register B                      */
57
58#define RTC_INTR       0x0c  /* status register C (R) interrupt source */
59#define  RTCIR_UPDATE  0x10  /* update intr                            */
60#define  RTCIR_ALARM   0x20  /* alarm intr                             */
61#define  RTCIR_PERIOD  0x40  /* periodic intr                          */
62#define  RTCIR_INT     0x80  /* interrupt output signal                */
63
64#define RTC_STATUSD    0x0d  /* status register D (R) Lost Power       */
65#define  RTCSD_PWR     0x80  /* clock lost power                       */
66
67#define RTC_DIAG       0x0e  /* status register E - bios diagnostic    */
68#define RTCDG_BITS     "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time"
69
70#define RTC_CENTURY    0x32  /* current century - increment in Dec99   */
71
72
73/*-------------------------------------------------------------------------+
74| Auxiliary Functions
75+--------------------------------------------------------------------------*/
76/*-------------------------------------------------------------------------+
77|         Function: bcd
78|      Description: Convert 2 digit number to its BCD representation.
79| Global Variables: None.
80|        Arguments: i - Number to convert.
81|          Returns: BCD representation of number.
82+--------------------------------------------------------------------------*/
83static inline rtems_unsigned8
84bcd(rtems_unsigned8 i)
85{
86  return ((i / 16) * 10 + (i % 16));
87} /* bcd */
88
89#define QUICK_READ  /* Quick read of the RTC: don't return number of seconds. */
90
91#ifndef QUICK_READ
92
93#define SECS_PER_DAY      (24 * 60 * 60)
94#define SECS_PER_REG_YEAR (365 * SECS_PER_DAY)
95
96/*-------------------------------------------------------------------------+
97|         Function: ytos
98|      Description: Convert years to seconds (since 1970).
99| Global Variables: None.
100|        Arguments: y - year to convert (1970 <= y <= 2100).
101|          Returns: number of seconds since 1970.
102+--------------------------------------------------------------------------*/
103static inline rtems_unsigned32
104ytos(rtems_unsigned16 y)
105{                                       /* v NUM LEAP YEARS v */
106  return ((y - 1970) * SECS_PER_REG_YEAR + (y - 1970 + 1) / 4 * SECS_PER_DAY);
107} /* ytos */
108
109
110/*-------------------------------------------------------------------------+
111|         Function: mtos
112|      Description: Convert months to seconds since January.
113| Global Variables: None.
114|        Arguments: m - month to convert, leap - is this a month of a leap year.
115|          Returns: number of seconds since January.
116+--------------------------------------------------------------------------*/
117static inline rtems_unsigned32
118mtos(rtems_unsigned8 m, rtems_boolean leap)
119{
120  static rtems_unsigned16 daysMonth[] = { 0, 0, 31,  59,  90, 120, 151, 181,
121                                               212, 243, 273, 304, 334, 365 };
122    /* Days since beginning of year until beginning of month. */
123
124  return ((daysMonth[m] + (leap ? 1 : 0)) * SECS_PER_DAY);
125} /* mtos */
126
127#endif /* QUICK_READ */
128
129/*-------------------------------------------------------------------------+
130|         Function: rtcin
131|      Description: Perform action on RTC and return its result.
132| Global Variables: None.
133|        Arguments: what - what to write to RTC port (what to do).
134|          Returns: result received from RTC port after action performed.
135+--------------------------------------------------------------------------*/
136static inline rtems_unsigned8
137rtcin(rtems_unsigned8 what)
138{
139    rtems_unsigned8 r;
140
141    outport_byte(IO_RTC,   what);
142    inport_byte (IO_RTC+1, r);
143    return r;
144} /* rtcin */
145
146
147/*-------------------------------------------------------------------------+
148| Functions
149+--------------------------------------------------------------------------*/
150/*-------------------------------------------------------------------------+
151|         Function: init_rtc
152|      Description: Initialize real-time clock (RTC).
153| Global Variables: None.
154|        Arguments: None.
155|          Returns: Nothing.
156+--------------------------------------------------------------------------*/
157void
158init_rtc(void)
159{
160  rtems_unsigned8 s;
161
162  /* initialize brain-dead battery powered clock */
163  outport_byte(IO_RTC,   RTC_STATUSA);
164  outport_byte(IO_RTC+1, 0x26);
165  outport_byte(IO_RTC,   RTC_STATUSB);
166  outport_byte(IO_RTC+1, 2);
167
168  outport_byte(IO_RTC,   RTC_DIAG);
169  inport_byte (IO_RTC+1, s);
170  if (s)
171    printk("RTC BIOS diagnostic error %b\n", s);
172
173  /* FIXME: This was last line's original version. How was it supposed to work?
174       printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS); */
175} /* init_rtc */
176
177
178/*-------------------------------------------------------------------------+
179|         Function: rtc_read
180|      Description: Read present time from RTC and return it.
181| Global Variables: None.
182|        Arguments: tod - to return present time in 'rtems_time_of_day' format.
183|          Returns: number of seconds from 1970/01/01 corresponding to 'tod'.
184+--------------------------------------------------------------------------*/
185long int
186rtc_read(rtems_time_of_day *tod)
187{
188  rtems_unsigned8  sa;
189  rtems_unsigned32 sec = 0;
190
191  memset(tod, 0, sizeof *tod); /* zero tod structure */
192
193  /* do we have a realtime clock present? (otherwise we loop below) */
194  sa = rtcin(RTC_STATUSA);
195  if (sa == 0xff || sa == 0)
196    return -1;
197
198  /* ready for a read? */
199  while ((sa&RTCSA_TUP) == RTCSA_TUP)
200    sa = rtcin(RTC_STATUSA);
201
202  tod->year     = bcd(rtcin(RTC_YEAR)) + 1900;  /* year    */
203  if (tod->year < 1970) tod->year += 100;       
204  tod->month    = bcd(rtcin(RTC_MONTH));        /* month   */
205  tod->day      = bcd(rtcin(RTC_DAY));          /* day     */
206  (void)          bcd(rtcin(RTC_WDAY));         /* weekday */
207  tod->hour     = bcd(rtcin(RTC_HRS));          /* hour    */
208  tod->minute   = bcd(rtcin(RTC_MIN));          /* minutes */
209  tod->second   = bcd(rtcin(RTC_SEC));          /* seconds */
210  tod->ticks    = 0;
211
212#ifndef QUICK_READ  /* Quick read of the RTC: don't return number of seconds. */
213  sec =  ytos(tod->year);
214  sec += mtos(tod->month, (tod->year % 4) == 0);
215  sec += tod->day * SECS_PER_DAY;
216  sec += tod->hour * 60 * 60;                     /* hour    */
217  sec += tod->minute * 60;                        /* minutes */
218  sec += tod->second;                             /* seconds */
219#endif /* QUICK_READ */
220
221  return (long int)sec;
222} /* rtc_read */
223
224
Note: See TracBrowser for help on using the repository browser.