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

📄 ds1307.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 * Dallas Semiconductor DS1307/DS1308 serial real-time clock chip. * This RTC have I2C bus interface. BSP have to provide I2C bus primitives * to make this driver working. getRegister and setRegister primitives is * not used here to avoid multiple transactions over I2C bus (each transaction * require significant time and error when date/time information red may * occurs). ulControlPort contains I2C bus number; ulDataPort contains * RTC I2C device address. * * Year 2000 Note: * * 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 00-87 are mapped to 2000-2087 *    + two digit years 88-99 are mapped to 1988-1999 * * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia * Author: Victor V. Vengerov <vvv@oktet.ru> * * 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: ds1307.c,v 1.2.2.1 2003/09/04 18:44:30 joel Exp $ */#include <rtems.h>#include <libchip/rtc.h>#include <string.h>#include "ds1307.h"#include "i2c.h"/* Convert from/to Binary-Coded Decimal representation */#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))#define To_BCD( _x )   ((((_x) / 10) << 4) + ((_x) % 10))/* ds1307_initialize -- *     Initialize DS1307 real-time clock chip. If RTC is halted, this *     function resume counting. * * PARAMETERS: *     minor -- minor RTC device number */voidds1307_initialize(int minor){    i2c_message_status status;    int try;    rtems_unsigned8 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)    {        rtems_unsigned8 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 */intds1307_get_time(int minor, rtems_time_of_day *time){    i2c_bus_number bus;    i2c_address addr;    rtems_unsigned8 info[8];    rtems_unsigned32 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 */intds1307_set_time(int minor, rtems_time_of_day *time){    i2c_bus_number bus;    i2c_address addr;    rtems_unsigned8 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};

⌨️ 快捷键说明

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