/*
 * Set time into chip
 */
int mc146818a_set_time(
  int                      minor,
  const rtems_time_of_day *time
)
{
  uint32_t     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;
}
Пример #2
0
static int m48t08_set_time(
  int                minor,
  const rtems_time_of_day *time
)
{
  uint32_t       m48t08;
  getRegister_f  getReg;
  setRegister_f  setReg;
  uint8_t        controlReg;

  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_WRITE );

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

  (*setReg)( m48t08, M48T08_YEAR,    To_BCD(time->year % 100) );
  (*setReg)( m48t08, M48T08_MONTH,   To_BCD(time->month) );
  (*setReg)( m48t08, M48T08_DATE,    To_BCD(time->day) );
  (*setReg)( m48t08, M48T08_HOUR,    To_BCD(time->hour) );
  (*setReg)( m48t08, M48T08_MINUTE,  To_BCD(time->minute) );
  (*setReg)( m48t08, M48T08_SECOND,  To_BCD(time->second) );

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

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

  return 0;
}
Пример #3
0
/* 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
};