![]() |
|
|||
File indexing completed on 2025-05-11 08:23:40
0001 /*-------------------------------------------------------------------------+ 0002 | rtc.c v1.1 - PC386 BSP - 1997/08/07 0003 +--------------------------------------------------------------------------+ 0004 | This file contains the real time clock manipulation package for the 0005 | PC386 board. 0006 +--------------------------------------------------------------------------+ 0007 | (C) Copyright 1997 - 0008 | - NavIST Group - Real-Time Distributed Systems and Industrial Automation 0009 | 0010 | http://pandora.ist.utl.pt 0011 | 0012 | Instituto Superior Tecnico * Lisboa * PORTUGAL 0013 +--------------------------------------------------------------------------+ 0014 | Disclaimer: 0015 | 0016 | This file is provided "AS IS" without warranty of any kind, either 0017 | expressed or implied. 0018 +--------------------------------------------------------------------------+ 0019 | This code is based on: 0020 | rtc.c,v 1.4 1995/12/19 20:07:15 joel Exp - go32 BSP 0021 | With the following copyright notice: 0022 | ************************************************************************** 0023 | * COPYRIGHT (c) 1989-1999. 0024 | * On-Line Applications Research Corporation (OAR). 0025 | * 0026 | * The license and distribution terms for this file may be 0027 | * found in the file LICENSE in this distribution or at 0028 | * http://www.rtems.org/license/LICENSE. 0029 | ************************************************************************** 0030 +--------------------------------------------------------------------------*/ 0031 0032 #include <string.h> 0033 0034 #include <bsp.h> 0035 0036 /*-------------------------------------------------------------------------+ 0037 | Constants 0038 +--------------------------------------------------------------------------*/ 0039 #define IO_RTC 0x70 /* RTC */ 0040 0041 #define RTC_SEC 0x00 /* seconds */ 0042 #define RTC_SECALRM 0x01 /* seconds alarm */ 0043 #define RTC_MIN 0x02 /* minutes */ 0044 #define RTC_MINALRM 0x03 /* minutes alarm */ 0045 #define RTC_HRS 0x04 /* hours */ 0046 #define RTC_HRSALRM 0x05 /* hours alarm */ 0047 #define RTC_WDAY 0x06 /* week day */ 0048 #define RTC_DAY 0x07 /* day of month */ 0049 #define RTC_MONTH 0x08 /* month of year */ 0050 #define RTC_YEAR 0x09 /* month of year */ 0051 #define RTC_STATUSA 0x0a /* status register A */ 0052 #define RTCSA_TUP 0x80 /* time update, don't look now */ 0053 0054 #define RTC_STATUSB 0x0b /* status register B */ 0055 0056 #define RTC_INTR 0x0c /* status register C (R) interrupt source */ 0057 #define RTCIR_UPDATE 0x10 /* update intr */ 0058 #define RTCIR_ALARM 0x20 /* alarm intr */ 0059 #define RTCIR_PERIOD 0x40 /* periodic intr */ 0060 #define RTCIR_INT 0x80 /* interrupt output signal */ 0061 0062 #define RTC_STATUSD 0x0d /* status register D (R) Lost Power */ 0063 #define RTCSD_PWR 0x80 /* clock lost power */ 0064 0065 #define RTC_DIAG 0x0e /* status register E - bios diagnostic */ 0066 #define RTCDG_BITS "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time" 0067 0068 #define RTC_CENTURY 0x32 /* current century - increment in Dec99 */ 0069 0070 /*-------------------------------------------------------------------------+ 0071 | Auxiliary Functions 0072 +--------------------------------------------------------------------------*/ 0073 /*-------------------------------------------------------------------------+ 0074 | Function: bcd 0075 | Description: Convert 2 digit number to its BCD representation. 0076 | Global Variables: None. 0077 | Arguments: i - Number to convert. 0078 | Returns: BCD representation of number. 0079 +--------------------------------------------------------------------------*/ 0080 static inline uint8_t 0081 bcd(uint8_t i) 0082 { 0083 return ((i / 16) * 10 + (i % 16)); 0084 } /* bcd */ 0085 0086 #define QUICK_READ /* Quick read of the RTC: don't return number of seconds. */ 0087 0088 #ifndef QUICK_READ 0089 0090 #define SECS_PER_DAY (24 * 60 * 60) 0091 #define SECS_PER_REG_YEAR (365 * SECS_PER_DAY) 0092 0093 /*-------------------------------------------------------------------------+ 0094 | Function: ytos 0095 | Description: Convert years to seconds (since 1970). 0096 | Global Variables: None. 0097 | Arguments: y - year to convert (1970 <= y <= 2100). 0098 | Returns: number of seconds since 1970. 0099 +--------------------------------------------------------------------------*/ 0100 static inline uint32_t 0101 ytos(uint16_t y) 0102 { /* v NUM LEAP YEARS v */ 0103 return ((y - 1970) * SECS_PER_REG_YEAR + (y - 1970 + 1) / 4 * SECS_PER_DAY); 0104 } /* ytos */ 0105 0106 /*-------------------------------------------------------------------------+ 0107 | Function: mtos 0108 | Description: Convert months to seconds since January. 0109 | Global Variables: None. 0110 | Arguments: m - month to convert, leap - is this a month of a leap year. 0111 | Returns: number of seconds since January. 0112 +--------------------------------------------------------------------------*/ 0113 static inline uint32_t 0114 mtos(uint8_t m, bool leap) 0115 { 0116 static uint16_t daysMonth[] = { 0, 0, 31, 59, 90, 120, 151, 181, 0117 212, 243, 273, 304, 334, 365 }; 0118 /* Days since beginning of year until beginning of month. */ 0119 0120 return ((daysMonth[m] + (leap ? 1 : 0)) * SECS_PER_DAY); 0121 } /* mtos */ 0122 0123 #endif /* QUICK_READ */ 0124 0125 /*-------------------------------------------------------------------------+ 0126 | Function: rtcin 0127 | Description: Perform action on RTC and return its result. 0128 | Global Variables: None. 0129 | Arguments: what - what to write to RTC port (what to do). 0130 | Returns: result received from RTC port after action performed. 0131 +--------------------------------------------------------------------------*/ 0132 static inline uint8_t 0133 rtcin(uint8_t what) 0134 { 0135 uint8_t r; 0136 0137 outport_byte(IO_RTC, what); 0138 inport_byte (IO_RTC+1, r); 0139 return r; 0140 } /* rtcin */ 0141 0142 /*-------------------------------------------------------------------------+ 0143 | Functions 0144 +--------------------------------------------------------------------------*/ 0145 /*-------------------------------------------------------------------------+ 0146 | Function: init_rtc 0147 | Description: Initialize real-time clock (RTC). 0148 | Global Variables: None. 0149 | Arguments: None. 0150 | Returns: Nothing. 0151 +--------------------------------------------------------------------------*/ 0152 void 0153 init_rtc(void) 0154 { 0155 uint8_t s; 0156 0157 /* initialize brain-dead battery powered clock */ 0158 outport_byte(IO_RTC, RTC_STATUSA); 0159 outport_byte(IO_RTC+1, 0x26); 0160 outport_byte(IO_RTC, RTC_STATUSB); 0161 outport_byte(IO_RTC+1, 2); 0162 0163 outport_byte(IO_RTC, RTC_DIAG); 0164 inport_byte (IO_RTC+1, s); 0165 if (s) 0166 printk("RTC BIOS diagnostic error %b\n", s); 0167 0168 /* FIXME: This was last line's original version. How was it supposed to work? 0169 printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS); */ 0170 } /* init_rtc */ 0171 0172 /*-------------------------------------------------------------------------+ 0173 | Function: rtc_read 0174 | Description: Read present time from RTC and return it. 0175 | Global Variables: None. 0176 | Arguments: tod - to return present time in 'rtems_time_of_day' format. 0177 | Returns: number of seconds from 1970/01/01 corresponding to 'tod'. 0178 +--------------------------------------------------------------------------*/ 0179 long int 0180 rtc_read(rtems_time_of_day *tod) 0181 { 0182 uint8_t sa; 0183 uint32_t sec = 0; 0184 0185 memset(tod, 0, sizeof *tod); /* zero tod structure */ 0186 0187 /* do we have a realtime clock present? (otherwise we loop below) */ 0188 sa = rtcin(RTC_STATUSA); 0189 if (sa == 0xff || sa == 0) 0190 return -1; 0191 0192 /* ready for a read? */ 0193 while ((sa&RTCSA_TUP) == RTCSA_TUP) 0194 sa = rtcin(RTC_STATUSA); 0195 0196 tod->year = bcd(rtcin(RTC_YEAR)) + 1900; /* year */ 0197 if (tod->year < 1970) tod->year += 100; 0198 tod->month = bcd(rtcin(RTC_MONTH)); /* month */ 0199 tod->day = bcd(rtcin(RTC_DAY)); /* day */ 0200 (void) bcd(rtcin(RTC_WDAY)); /* weekday */ 0201 tod->hour = bcd(rtcin(RTC_HRS)); /* hour */ 0202 tod->minute = bcd(rtcin(RTC_MIN)); /* minutes */ 0203 tod->second = bcd(rtcin(RTC_SEC)); /* seconds */ 0204 tod->ticks = 0; 0205 0206 #ifndef QUICK_READ /* Quick read of the RTC: don't return number of seconds. */ 0207 sec = ytos(tod->year); 0208 sec += mtos(tod->month, (tod->year % 4) == 0); 0209 sec += tod->day * SECS_PER_DAY; 0210 sec += tod->hour * 60 * 60; /* hour */ 0211 sec += tod->minute * 60; /* minutes */ 0212 sec += tod->second; /* seconds */ 0213 #endif /* QUICK_READ */ 0214 0215 return (long int)sec; 0216 } /* rtc_read */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |