⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mc146818a.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* *  This file interfaces with the real-time clock found in  *  a Motorola MC146818A (common on PC hardware) * *  Year 2K Notes: * *  This chip only uses a two digit field to store the year.  This *  code uses the RTEMS Epoch as a pivot year.  This lets us map the *  two digit year field as follows: * *    + two digit years 0-87 are mapped to 2000-2087. *    + two digit years 88-99 are mapped to 1988-1999. * *  This is less than the time span supported by RTEMS. * *  COPYRIGHT (c) 1989-1999. *  On-Line Applications Research Corporation (OAR). * *  The license and distribution terms for this file may be *  found in the file LICENSE in this distribution or at *  http://www.rtems.com/license/LICENSE. * *  $Id: mc146818a.c,v 1.2.2.2 2004/11/10 22:27:08 joel Exp $ */#include <rtems.h>#include <libchip/rtc.h>#include <libchip/mc146818a.h>#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))#define To_BCD( _x )   ((((_x) / 10) << 4) + ((_x) % 10))/* * See if chip is present */boolean mc146818a_probe(  int minor){  unsigned32     mc146818a;  getRegister_f  getReg;  unsigned32     value;  /*   * Verify that chip is present and that time is valid   */  mc146818a = RTC_Table[ minor ].ulCtrlPort1;  getReg = RTC_Table[ minor ].getRegister;  value = (*getReg)( mc146818a, MC146818A_STATUSD );  if ((value == 0) || (value == 0xFF))    return FALSE;  return TRUE;}/* * Initialize chip */void mc146818a_initialize(  int minor){  unsigned32     mc146818a;  getRegister_f  getReg;  setRegister_f  setReg;  mc146818a = RTC_Table[ minor ].ulCtrlPort1;  getReg = RTC_Table[ minor ].getRegister;  setReg = RTC_Table[ minor ].setRegister;  (*setReg)( mc146818a, MC146818A_STATUSA, MC146818ASA_DIVIDER|MC146818ASA_1024 );  (*setReg)( mc146818a, MC146818A_STATUSB, MC146818ASB_24HR );}/* * Read time from chip */int mc146818a_get_time(  int                minor,  rtems_time_of_day *time){  unsigned32     mc146818a;  getRegister_f  getReg;  unsigned32     value;  rtems_interrupt_level level;  mc146818a = RTC_Table[ minor ].ulCtrlPort1;  getReg = RTC_Table[ minor ].getRegister;  /*   * No time if power failed   */  if (((*getReg)( mc146818a, MC146818A_STATUSD ) & MC146818ASD_PWR) == 0)    return -1;  /*   * Wait for time update to complete   */  rtems_interrupt_disable( level );  while (((*getReg)( mc146818a, MC146818A_STATUSA ) & MC146818ASA_TUP) != 0) {      rtems_interrupt_flash( level );  }    /*   * Read the time (we have at least 244 usec to do this)   */  value = (*getReg)( mc146818a, MC146818A_YEAR );  value = From_BCD( value );  if ( value < 88 )    time->year = 2000 + value;  else    time->year = 1900 + value;  value = (*getReg)( mc146818a, MC146818A_MONTH );  time->month = From_BCD( value );  value = (*getReg)( mc146818a, MC146818A_DAY );  time->day = From_BCD( value );  value = (*getReg)( mc146818a, MC146818A_HRS );  time->hour = From_BCD( value );  value = (*getReg)( mc146818a, MC146818A_MIN );  time->minute = From_BCD( value );  value = (*getReg)( mc146818a, MC146818A_SEC );  rtems_interrupt_enable( level );  time->second = From_BCD( value );  time->ticks  = 0;  return 0;}/* * Set time into chip */int mc146818a_set_time(  int                minor,  rtems_time_of_day *time){  unsigned32     mc146818a;  getRegister_f  getReg;  setRegister_f  setReg;  mc146818a = RTC_Table[ minor ].ulCtrlPort1;  getReg = RTC_Table[ minor ].getRegister;  setReg = RTC_Table[ minor ].setRegister;  /*   * Stop the RTC   */  (*setReg)( mc146818a, MC146818A_STATUSB, MC146818ASB_HALT|MC146818ASB_24HR );    if ( time->year >= 2088 )    rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );  (*setReg)( mc146818a, MC146818A_YEAR,  To_BCD(time->year % 100) );  (*setReg)( mc146818a, MC146818A_MONTH, To_BCD(time->month) );  (*setReg)( mc146818a, MC146818A_DAY,   To_BCD(time->day) );  (*setReg)( mc146818a, MC146818A_HRS,   To_BCD(time->hour) );  (*setReg)( mc146818a, MC146818A_MIN,   To_BCD(time->minute) );  (*setReg)( mc146818a, MC146818A_SEC,   To_BCD(time->second) );   /*   * Restart the RTC   */  (*setReg)( mc146818a, MC146818A_STATUSB, MC146818ASB_24HR );  return 0;}/* *  Driver function table */rtc_fns mc146818a_fns = {  mc146818a_initialize,  mc146818a_get_time,  mc146818a_set_time};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -