source: rtems/c/src/lib/libbsp/m68k/mcf5206elite/tod/ds1307.c @ e56c3546

4.104.114.84.95
Last change on this file since e56c3546 was e56c3546, checked in by Joel Sherrill <joel.sherrill@…>, on 10/26/01 at 19:30:11

2001-10-26 Victor V. Vengerov <vvv@…>

  • New BSP for MCF5206eLITE evaluation board BSP.
  • ChangeLog?, README, bsp_specs, configure.ac, console/console.c, console/.cvsignore, i2c/i2c.c, i2c/i2cdrv.c, i2c/.cvsignore, include/bsp.h, include/bspopts.h.in, include/coverhd.h, include/ds1307.h, include/i2c.h, include/i2cdrv.h, include/nvram.h, include/.cvsignore, nvram/nvram.c, nvram/.cvsignore, start/start.S, start/.cvsignore, startup/bspclean.c, startup/bspstart.c, startup/gdbinit, startup/init5206e.c, startup/linkcmds, startup/linkcmds.flash, startup/.cvsignore, times, tod/ds1307.c, tod/todcfg.c, tod/.cvsignore, tools/.cvsignore, tools/configure.ac, tools/runtest, tools/changes, wrapup/.cvsignore, .cvsignore: New files.
  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 * This file interfaces with the real-time clock found in a
3 * Dallas Semiconductor DS1307/DS1308 serial real-time clock chip.
4 * This RTC have I2C bus interface. BSP have to provide I2C bus primitives
5 * to make this driver working. getRegister and setRegister primitives is
6 * not used here to avoid multiple transactions over I2C bus (each transaction
7 * require significant time and error when date/time information red may
8 * occurs). ulControlPort contains I2C bus number; ulDataPort contains
9 * RTC I2C device address.
10 *
11 * Year 2000 Note:
12 *
13 * This chip only uses a two digit field to store the year. This code
14 * uses the RTEMS Epoch as a pivot year. This lets us map the two digit
15 * year field as follows:
16 *
17 *    + two digit years 00-87 are mapped to 2000-2087
18 *    + two digit years 88-99 are mapped to 1988-1999
19 *
20 * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
21 * Author: Victor V. Vengerov <vvv@oktet.ru>
22 *
23 * The license and distribution terms for this file may be
24 * found in the file LICENSE in this distribution or at
25 *
26 * http://www.OARcorp.com/rtems/license.html.
27 *
28 * @(#) $Id$
29 */
30
31#include <rtems.h>
32#include <libchip/rtc.h>
33#include "ds1307.h"
34#include "i2c.h"
35
36/* Convert from/to Binary-Coded Decimal representation */
37#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))
38#define To_BCD( _x )   ((((_x) / 10) << 4) + ((_x) % 10))
39
40/* ds1307_initialize --
41 *     Initialize DS1307 real-time clock chip. If RTC is halted, this
42 *     function resume counting.
43 *
44 * PARAMETERS:
45 *     minor -- minor RTC device number
46 */
47void
48ds1307_initialize(int minor)
49{
50    i2c_message_status status;
51    int try;
52    rtems_unsigned8 sec;
53    i2c_bus_number bus;
54    i2c_address addr;
55   
56    bus = RTC_Table[minor].ulCtrlPort1;
57    addr = RTC_Table[minor].ulDataPort;
58   
59    /* Read SECONDS register */
60    try = 0;
61    do {
62        status = i2c_wbrd(bus, addr, 0, &sec, sizeof(sec));
63        try++;
64    } while ((status != I2C_SUCCESSFUL) && (try < 15));
65   
66    /* If clock is halted, reset and start the clock */
67    if ((sec & DS1307_SECOND_HALT) != 0)
68    {
69        rtems_unsigned8 start[8];
70        memset(start, 0, sizeof(start));
71        start[0] = DS1307_SECOND;
72        try = 0;
73        do {
74            status = i2c_write(bus, addr, start, 2);
75        } while ((status != I2C_SUCCESSFUL) && (try < 15));
76    }
77}
78
79/* ds1307_get_time --
80 *     read current time from DS1307 real-time clock chip and convert it
81 *     to the rtems_time_of_day structure.
82 *
83 * PARAMETERS:
84 *     minor -- minor RTC device number
85 *     time -- place to put return value (date and time)
86 *
87 * RETURNS:
88 *     0, if time obtained successfully
89 *     -1, if error occured
90 */
91int
92ds1307_get_time(int minor, rtems_time_of_day *time)
93{
94    i2c_bus_number bus;
95    i2c_address addr;
96    rtems_unsigned8 info[8];
97    rtems_unsigned32 v1, v2;
98    i2c_message_status status;
99    int try;
100   
101    if (time == NULL)
102        return -1;
103   
104    bus = RTC_Table[minor].ulCtrlPort1;
105    addr = RTC_Table[minor].ulDataPort;
106   
107    memset(time, 0, sizeof(rtems_time_of_day));
108    try = 0;
109    do {
110        status = i2c_wbrd(bus, addr, 0, info, sizeof(info));
111        try++;
112    } while ((status != I2C_SUCCESSFUL) && (try < 10));
113
114    if (status != I2C_SUCCESSFUL)
115    {
116        return -1;
117    }
118   
119    v1 = info[DS1307_YEAR];
120    v2 = From_BCD(v1);
121    if (v2 < 88)
122        time->year = 2000 + v2;
123    else
124        time->year = 1900 + v2;
125   
126    v1 = info[DS1307_MONTH] & ~0xE0;
127    time->month = From_BCD(v1);
128   
129    v1 = info[DS1307_DAY] & ~0xC0;
130    time->day = From_BCD(v1);
131   
132    v1 = info[DS1307_HOUR];
133    if (v1 & DS1307_HOUR_12)
134    {
135        v2 = v1 & ~0xE0;
136        if (v1 & DS1307_HOUR_PM)
137        {
138            time->hour = From_BCD(v2) + 12;
139        }
140        else
141        {
142            time->hour = From_BCD(v2);
143        }
144    }
145    else
146    {
147        v2 = v1 & ~0xC0;
148        time->hour = From_BCD(v2);
149    }
150
151    v1 = info[DS1307_MINUTE] & ~0x80;
152    time->minute = From_BCD(v1);
153   
154    v1 = info[DS1307_SECOND];
155    v2 = v1 & ~0x80;
156    time->second = From_BCD(v2);
157   
158    return 0;
159}
160
161/* ds1307_set_time --
162 *     set time to the DS1307 real-time clock chip
163 *
164 * PARAMETERS:
165 *     minor -- minor RTC device number
166 *     time -- new date and time to be written to DS1307
167 *
168 * RETURNS:
169 *     0, if time obtained successfully
170 *     -1, if error occured
171 */
172int
173ds1307_set_time(int minor, rtems_time_of_day *time)
174{
175    i2c_bus_number bus;
176    i2c_address addr;
177    rtems_unsigned8 info[8];
178    i2c_message_status status;
179    int try;
180   
181    if (time == NULL)
182        return -1;
183
184    bus = RTC_Table[minor].ulCtrlPort1;
185    addr = RTC_Table[minor].ulDataPort;
186
187    if (time->year >= 2088)
188        rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER);
189   
190    info[0] = DS1307_SECOND;
191    info[1 + DS1307_YEAR] = To_BCD(time->year % 100);
192    info[1 + DS1307_MONTH] = To_BCD(time->month);
193    info[1 + DS1307_DAY] = To_BCD(time->day);
194    info[1 + DS1307_HOUR] = To_BCD(time->hour);
195    info[1 + DS1307_MINUTE] = To_BCD(time->minute);
196    info[1 + DS1307_SECOND] = To_BCD(time->second);
197    info[1 + DS1307_DAY_OF_WEEK] = 1; /* Do not set day of week */
198 
199    try = 0;
200    do {
201        status = i2c_write(bus, addr, info, 8);
202        try++;
203    } while ((status != I2C_SUCCESSFUL) && (try < 10));
204
205    if (status != I2C_SUCCESSFUL)
206        return -1;
207    else
208        return 0;
209}
210
211/* Driver function table */
212
213rtc_fns ds1307_fns = {
214    ds1307_initialize,
215    ds1307_get_time,
216    ds1307_set_time
217};
Note: See TracBrowser for help on using the repository browser.