source: rtems/c/src/libchip/rtc/mc146818a.c @ f619250

4.115
Last change on this file since f619250 was aa314cf, checked in by Andreas Heinig <andreas.heinig@…>, on 02/28/13 at 17:08:50

libchip/rtc: Fixed 19 compiler warnings

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*
2 *  This file interfaces with the real-time clock found in
3 *  a Motorola MC146818A (common on PC hardware)
4 *
5 *  Year 2K Notes:
6 *
7 *  This chip only uses a two digit field to store the year.  This
8 *  code uses the RTEMS Epoch as a pivot year.  This lets us map the
9 *  two digit year field as follows:
10 *
11 *    + two digit years 0-87 are mapped to 2000-2087.
12 *    + two digit years 88-99 are mapped to 1988-1999.
13 *
14 *  This is less than the time span supported by RTEMS.
15 *
16 *  COPYRIGHT (c) 1989-1999.
17 *  On-Line Applications Research Corporation (OAR).
18 *
19 *  The license and distribution terms for this file may be
20 *  found in the file LICENSE in this distribution or at
21 *  http://www.rtems.com/license/LICENSE.
22 */
23#include <rtems.h>
24#include <libchip/rtc.h>
25#include <libchip/mc146818a.h>
26
27#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))
28#define To_BCD( _x )   ((((_x) / 10) << 4) + ((_x) % 10))
29
30/*
31 * See if chip is present
32 */
33bool mc146818a_probe(
34  int minor
35)
36{
37  uint32_t     mc146818a;
38  getRegister_f  getReg;
39  uint32_t     value;
40
41  /*
42   * Verify that chip is present and that time is valid
43   */
44  mc146818a = RTC_Table[ minor ].ulCtrlPort1;
45  getReg = RTC_Table[ minor ].getRegister;
46  value = (*getReg)( mc146818a, MC146818A_STATUSD );
47  if ((value == 0) || (value == 0xFF))
48    return false;
49  return true;
50}
51
52/*
53 * Initialize chip
54 */
55static void mc146818a_initialize(
56  int minor
57)
58{
59  uint32_t     mc146818a;
60  setRegister_f  setReg;
61
62  mc146818a = RTC_Table[ minor ].ulCtrlPort1;
63  setReg = RTC_Table[ minor ].setRegister;
64
65  (*setReg)( mc146818a, MC146818A_STATUSA, MC146818ASA_DIVIDER|MC146818ASA_1024 );
66  (*setReg)( mc146818a, MC146818A_STATUSB, MC146818ASB_24HR );
67}
68
69/*
70 * Read time from chip
71 */
72static int mc146818a_get_time(
73  int                minor,
74  rtems_time_of_day *time
75)
76{
77  uint32_t     mc146818a;
78  getRegister_f  getReg;
79  uint32_t     value;
80  rtems_interrupt_level level;
81
82  mc146818a = RTC_Table[ minor ].ulCtrlPort1;
83  getReg = RTC_Table[ minor ].getRegister;
84
85  /*
86   * No time if power failed
87   */
88  if (((*getReg)( mc146818a, MC146818A_STATUSD ) & MC146818ASD_PWR) == 0)
89    return -1;
90
91  /*
92   * Wait for time update to complete
93   */
94  rtems_interrupt_disable( level );
95  while (((*getReg)( mc146818a, MC146818A_STATUSA ) & MC146818ASA_TUP) != 0) {
96      rtems_interrupt_flash( level );
97  }
98
99  /*
100   * Read the time (we have at least 244 usec to do this)
101   */
102  value = (*getReg)( mc146818a, MC146818A_YEAR );
103  value = From_BCD( value );
104  if ( value < 88 )
105    time->year = 2000 + value;
106  else
107    time->year = 1900 + value;
108
109  value = (*getReg)( mc146818a, MC146818A_MONTH );
110  time->month = From_BCD( value );
111
112  value = (*getReg)( mc146818a, MC146818A_DAY );
113  time->day = From_BCD( value );
114
115  value = (*getReg)( mc146818a, MC146818A_HRS );
116  time->hour = From_BCD( value );
117
118  value = (*getReg)( mc146818a, MC146818A_MIN );
119  time->minute = From_BCD( value );
120
121  value = (*getReg)( mc146818a, MC146818A_SEC );
122  rtems_interrupt_enable( level );
123  time->second = From_BCD( value );
124  time->ticks  = 0;
125
126  return 0;
127}
128
129/*
130 * Set time into chip
131 */
132static int mc146818a_set_time(
133  int                      minor,
134  const rtems_time_of_day *time
135)
136{
137  uint32_t     mc146818a;
138  setRegister_f  setReg;
139
140  mc146818a = RTC_Table[ minor ].ulCtrlPort1;
141  setReg = RTC_Table[ minor ].setRegister;
142
143  /*
144   * Stop the RTC
145   */
146  (*setReg)( mc146818a, MC146818A_STATUSB, MC146818ASB_HALT|MC146818ASB_24HR );
147
148  if ( time->year >= 2088 )
149    rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );
150
151  (*setReg)( mc146818a, MC146818A_YEAR,  To_BCD(time->year % 100) );
152  (*setReg)( mc146818a, MC146818A_MONTH, To_BCD(time->month) );
153  (*setReg)( mc146818a, MC146818A_DAY,   To_BCD(time->day) );
154  (*setReg)( mc146818a, MC146818A_HRS,   To_BCD(time->hour) );
155  (*setReg)( mc146818a, MC146818A_MIN,   To_BCD(time->minute) );
156  (*setReg)( mc146818a, MC146818A_SEC,   To_BCD(time->second) );
157
158  /*
159   * Restart the RTC
160   */
161  (*setReg)( mc146818a, MC146818A_STATUSB, MC146818ASB_24HR );
162  return 0;
163}
164
165/*
166 *  Driver function table
167 */
168rtc_fns mc146818a_fns = {
169  mc146818a_initialize,
170  mc146818a_get_time,
171  mc146818a_set_time
172};
Note: See TracBrowser for help on using the repository browser.