/*
 * Read time from chip
 */
int mc146818a_get_time(
  int                minor,
  rtems_time_of_day *time
)
{
  uint32_t     mc146818a;
  getRegister_f  getReg;
  uint32_t     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;
}
예제 #2
0
파일: m48t08.c 프로젝트: epicsdeb/rtems
static int m48t08_get_time(
  int                minor,
  rtems_time_of_day *time
)
{
  uint32_t       m48t08;
  getRegister_f  getReg;
  setRegister_f  setReg;
  uint8_t        controlReg;
  uint32_t       value1;
  uint32_t       value2;

  m48t08 = RTC_Table[ minor ].ulCtrlPort1;
  getReg = RTC_Table[ minor ].getRegister;
  setReg = RTC_Table[ minor ].setRegister;

  /*
   *  Put the RTC into read mode
   */

  controlReg = (*getReg)( m48t08, M48T08_CONTROL );
  (*setReg)( m48t08, M48T08_CONTROL, controlReg | M48T08_CONTROL_READ );

  value1 = (*getReg)( m48t08, M48T08_YEAR );
  value2 = From_BCD( value1 );
  if ( value2 < 88 )
    time->year = 2000 + value2;
  else
    time->year = 1900 + value2;

  value1 = (*getReg)( m48t08, M48T08_MONTH );
  time->month = From_BCD( value1 );

  value1 = (*getReg)( m48t08, M48T08_DATE );
  time->day = From_BCD( value1 );

  value1 = (*getReg)( m48t08, M48T08_HOUR );
  time->hour = From_BCD( value1 );

  value1 = (*getReg)( m48t08, M48T08_MINUTE );
  time->minute = From_BCD( value1 );

  value1 = (*getReg)( m48t08, M48T08_SECOND );
  time->second = From_BCD( value1 );

  time->ticks  = 0;

  /*
   *  Put the RTC back into normal mode.
   */

  (*setReg)( m48t08, M48T08_CONTROL, controlReg );

  return 0;
}
예제 #3
0
파일: ds1307.c 프로젝트: epicsdeb/rtems
/* ds1307_initialize --
 *     Initialize DS1307 real-time clock chip. If RTC is halted, this
 *     function resume counting.
 *
 * PARAMETERS:
 *     minor -- minor RTC device number
 */
void
ds1307_initialize(int minor)
{
    i2c_message_status status;
    int try;
    uint8_t         sec;
    i2c_bus_number bus;
    i2c_address addr;

    bus = RTC_Table[minor].ulCtrlPort1;
    addr = RTC_Table[minor].ulDataPort;

    /* Read SECONDS register */
    try = 0;
    do {
        status = i2c_wbrd(bus, addr, 0, &sec, sizeof(sec));
        try++;
    } while ((status != I2C_SUCCESSFUL) && (try < 15));

    /* If clock is halted, reset and start the clock */
    if ((sec & DS1307_SECOND_HALT) != 0)
    {
        uint8_t         start[8];
        memset(start, 0, sizeof(start));
        start[0] = DS1307_SECOND;
        try = 0;
        do {
            status = i2c_write(bus, addr, start, 2);
        } while ((status != I2C_SUCCESSFUL) && (try < 15));
    }
}

/* ds1307_get_time --
 *     read current time from DS1307 real-time clock chip and convert it
 *     to the rtems_time_of_day structure.
 *
 * PARAMETERS:
 *     minor -- minor RTC device number
 *     time -- place to put return value (date and time)
 *
 * RETURNS:
 *     0, if time obtained successfully
 *     -1, if error occured
 */
int
ds1307_get_time(int minor, rtems_time_of_day *time)
{
    i2c_bus_number bus;
    i2c_address addr;
    uint8_t         info[8];
    uint32_t         v1, v2;
    i2c_message_status status;
    int try;

    if (time == NULL)
        return -1;

    bus = RTC_Table[minor].ulCtrlPort1;
    addr = RTC_Table[minor].ulDataPort;

    memset(time, 0, sizeof(rtems_time_of_day));
    try = 0;
    do {
        status = i2c_wbrd(bus, addr, 0, info, sizeof(info));
        try++;
    } while ((status != I2C_SUCCESSFUL) && (try < 10));

    if (status != I2C_SUCCESSFUL)
    {
        return -1;
    }

    v1 = info[DS1307_YEAR];
    v2 = From_BCD(v1);
    if (v2 < 88)
        time->year = 2000 + v2;
    else
        time->year = 1900 + v2;

    v1 = info[DS1307_MONTH] & ~0xE0;
    time->month = From_BCD(v1);

    v1 = info[DS1307_DAY] & ~0xC0;
    time->day = From_BCD(v1);

    v1 = info[DS1307_HOUR];
    if (v1 & DS1307_HOUR_12)
    {
        v2 = v1 & ~0xE0;
        if (v1 & DS1307_HOUR_PM)
        {
            time->hour = From_BCD(v2) + 12;
        }
        else
        {
            time->hour = From_BCD(v2);
        }
    }
    else
    {
        v2 = v1 & ~0xC0;
        time->hour = From_BCD(v2);
    }

    v1 = info[DS1307_MINUTE] & ~0x80;
    time->minute = From_BCD(v1);

    v1 = info[DS1307_SECOND];
    v2 = v1 & ~0x80;
    time->second = From_BCD(v2);

    return 0;
}

/* ds1307_set_time --
 *     set time to the DS1307 real-time clock chip
 *
 * PARAMETERS:
 *     minor -- minor RTC device number
 *     time -- new date and time to be written to DS1307
 *
 * RETURNS:
 *     0, if time obtained successfully
 *     -1, if error occured
 */
int
ds1307_set_time(int minor, const rtems_time_of_day *time)
{
    i2c_bus_number bus;
    i2c_address addr;
    uint8_t         info[8];
    i2c_message_status status;
    int try;

    if (time == NULL)
        return -1;

    bus = RTC_Table[minor].ulCtrlPort1;
    addr = RTC_Table[minor].ulDataPort;

    if (time->year >= 2088)
        rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER);

    info[0] = DS1307_SECOND;
    info[1 + DS1307_YEAR] = To_BCD(time->year % 100);
    info[1 + DS1307_MONTH] = To_BCD(time->month);
    info[1 + DS1307_DAY] = To_BCD(time->day);
    info[1 + DS1307_HOUR] = To_BCD(time->hour);
    info[1 + DS1307_MINUTE] = To_BCD(time->minute);
    info[1 + DS1307_SECOND] = To_BCD(time->second);
    info[1 + DS1307_DAY_OF_WEEK] = 1; /* Do not set day of week */

    try = 0;
    do {
        status = i2c_write(bus, addr, info, 8);
        try++;
    } while ((status != I2C_SUCCESSFUL) && (try < 10));

    if (status != I2C_SUCCESSFUL)
        return -1;
    else
        return 0;
}

/* Driver function table */

rtc_fns ds1307_fns = {
    ds1307_initialize,
    ds1307_get_time,
    ds1307_set_time
};